我是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)。为什么我的代码更快?
答案 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)。