三色旗问题

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色
在这里插入图片描述
解法
三路归并,其实也是 Arrays.sort() 这里采用的方法,也是三色旗的解决方案。

三个指针,分别是 left、cur、right。left指向数组最左侧,right指向数组最右侧,cur代表当前正在遍历的数组元素,当 cur 遍历的元素是 0 时,将 cur 指向的元素 与 p0 指向的元素交换,然后 cur++,p0++。当 cur 遍历的元素是 1 时,cur++。当 cur 遍历的元素是 2 时,将 cur 指向的元素与 p2 指向的元素交换,然后 p2–,cur不动!!!直到 cur > p2 ,循环结束(即全部扫描完毕)。

对于以上,有一个难点!为何 cur 在于 p0 交换时需要 p0++,cur++;而在 cur 与 p2 交换时,却只需要 p2++
对于上面这个问题,有两种解释思路:1.cur 与 p0 交换需要自加,是因为其左边已经扫描过了,交换过来的值也是之前就扫描过了的,而右边不是, p2 交换过来的值 cur 并没有扫描过;2.当 cur 与 p0 不是一个指向同一个索引值时,那 cur 指向的索引值如果发生交换,那交换过来的一定是 1(原因是只有当遍历过的节点有1,p0 和 cur 才不会同步),而 如果索引是 1 刚好也就不用有任何操作,所以可以直接继续向右扫描,当 cur 和 p0 指向的是同一个索引,那交换就等于没交换,故也是直接可以向右扫描,右边的就不行。

#75 排序,不使用额外空间
def sord_colors(nums):
    n = len(nums)
    if n <= 1:
        return nums
    left_index,right_index = 0,n-1
    cur_index = 0
    while cur_index<=right_index:
        if nums[cur_index] == 0:
            nums[cur_index],nums[left_index] = nums[left_index],nums[cur_index]
            left_index += 1
            cur_index += 1 #这里需要加一是因为:cur_index左边的元素已经遍历过了,所以交换之后的这个元素是已经判断过的,所以不需要在判断了
        elif nums[cur_index] == 2:
            nums[cur_index],nums[right_index] = nums[right_index],nums[cur_index]
            right_index -= 1#这里没有把cur_index加1是因为:cur_index右边的元素还没有哦判断,所以交换之后的元素还需要在判断一下
        else:
            cur_index += 1
    return nums

nums = [2,0,2,1,1,0]
sord_colors(nums) #Out[28]: [0, 0, 1, 1, 2, 2]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值