在O(n)中运行的荷兰国旗问题

时间:2019-04-05 14:13:19

标签: python-3.x sorting dutch-national-flag-problem

我是CompSci 1的10年级学生。在我们的教科书Practical Programming 3rd Edition, An Introduction to Computer Science Using Python 3.6中,它提到了荷兰国旗问题。下面是它如何逐字说明练习的方式:

  

Edsgar Dijkstra以其在编程语言方面的工作而闻名。他提出了一个巧妙的问题,他称之为荷兰国旗问题:给出了一个字符串列表,每个字符串都是“红色”,“绿色”或“蓝色”(在列表中多次代表),重新排列列表,使字符串按荷兰国旗的顺序排列-首先是所有“红色”字符串,然后是所有“绿色”字符串,然后是所有“蓝色”字符串。

这是我为练习编写的python代码:

def dutch_flag(colors: list)-> list:
  """
  This function takes a list of strings of colors (red, green, 
  or blue),and returns a list containing them with the reds first, 
  the greens second, and the blues last.
  """
  reds = 0
  greens = 0
  blues = 0
  for color in colors:
    color = color.lower().strip()
    if color == "red":
      reds += 1
    elif color == "green":
      greens += 1
    elif color == "blue":
      blues += 1

  flag = []
  for i in range(0, reds):
    flag.append("red")
  for i in range(0, greens):
    flag.append("green")
  for i in range(0, blues):
    flag.append("blue")

  return flag  

我的代码运行时间为O(n)。但是,我的老师告诉我们,该程序需要一个排序算法,充其量最好是O(n * logn)。为什么我的代码更快?

1 个答案:

答案 0 :(得分:1)

您显示的是一种计数排序。其他非比较选项可能是存储桶或基数排序,它们也具有O(n)时间复杂度。

使用基于比较的三向分区函数来解决此问题也是可能的,该函数使用比较和交换来处理时间复杂度为O(n)。

https://en.wikipedia.org/wiki/Dutch_national_flag_problem#Pseudocode

通常,基于比较的排序需要O(n log(n))时间,但荷兰国旗问题不需要这样做。

可以扩展三向分割功能以处理更多颜色。第一遍将数组分成3个子数组(小,中,大),然后在每个子数组上重复该过程,将其分成3个子子数组,依此类推。 2遍可以完成9种颜色,第1遍将小,中,大分为三个部分,然后第2遍将每个子阵列分成3个部分,这也是O(n)时间复杂性。对于n个元素和k种颜色,时间复杂度为O(n⌈log3(k)⌉),但是由于k为常数,所以时间复杂度为O(n)。