问题描述:
荷兰国旗仅有红、白、蓝三色构成。设有一个仅有红、白、蓝三种颜色的n个条块组成的条块序列,请设计一个时间复杂度为O(n)的算法使得这些红、白、蓝的顺序排好,也就是构成荷兰国旗的。
问题分析:
这个问题是一道经典的数组排序问题,由于本体要求时间复杂度为O(n),即只能遍历数组中每个元素一次,这里我们采用快速排序算法的思想来解决这个问题。
首先将问题抽象化,我们可以用一个数组来存放这三种颜色的条块,红白蓝分别对应0、1、2。初始时三种颜色的条块是无序的,要求排序后的数组元素按照0->1->2的顺序排列。例如,包含7个条块的数组[0,1,2,0,0,2,1],排序后变为[0,0,0,1,1,2,2]。
思路如下:
设置两个标志位left和right分别指向这个数组的开始和末尾,然后用一个标志位current从头开始进行遍历:
1)若current遍历到的元素为0,就和left所在位置的元素进行交换,将0移到左边,然后current向前进1,left也向前进1
2)若current遍历到的元素为1,则说明它一定属于中部,然后current向前进1。
3)若current遍历到的元素为2,就和right所在位置的元素进行交换,将2移到右边,然后end向后退1,curent位置不变,继续判断current当前位置的元素。
直到 current > right时,循环中止,排序完成。
从上述思路可以看出,循环最多只会遍历数组一次,因此最坏情况下时间复杂度为O(n)。
代码如下:
def guoqipaixu(a):
left = 0
right = len(a) - 1
current = 0
while current <= right:
if a[current] == 0:
a[current], a[left] = a[left], a[current]
left += 1
current += 1
elif a[current] == 1:
current += 1
else:
a[current], a[right] = a[right], a[current]
right -= 1
if __name__ == '__main__':
a = [0,1,2,0,0,2,1]
guoqipaixu(a)
print(a)