leetcode专题训练 75. Sort Colors

  1. 初始解法

最开始的想法是用三个指针来解决该问题,分别是left, right和tmp。其中
nums[idx<left]=0nums[left]!=0(1)nums[idx>right]=2nums[right]!=2(2) nums[idx<left] = 0 且 nums[left] !=0\qquad (1)\\ nums[idx>right] = 2且nums[right]!= 2\qquad (2)
也就是left和right代表着最长0串或2串的边界。tmp指针指向当前正在处理的位置。
而出于对于特殊情况的考虑,先判断nums是否为空,若为空,则直接返回。
接下来为了达到(1)(2)式的要求,先用循环将left和right的初始位置设置好。

while left < right and nums[left] == 0:
    left += 1
while left < right and nums[right] == 2:
    right -= 1

此时就可以开始处理left和right之间的数组。处理方式就是用tmp指针扫一遍数组,将扫到的0放到左边,扫到的2放到右边。具体的处理方式是,如果扫到0,那么就将nums[left]与nums[tmp]替换,同时将left指针右移一格;如果扫到2,那么就考察nums[right]的值,如果值为0,那么就可以在更新nums[right]的值的同时更新nums[left]的值,将left和right的值同时移动,如果值不为0,那么就将nums[left]与nums[tmp]替换,right左移一格。此处需要注意,由于left在tmp左边,所以nums[left]只有可能是1,所以扫到0的时候不用考察nums[left]的值就可以直接替换。
在进行如上更新后,可能此时的nums[left]为0,nums[right]为2,所以又要进行left和right的更新,使得此时的left和right达到(1)(2)式的要求。而tmp也要根据left进行更新,如果left更新后到了tmp的右边,那么就将tmp更新为此时的left。
tmp指针扫完left和right之间的数组,也就是tmp>right的时候,整个算法就已经完成了。就地排序完成。
总体代码如下:

class Solution:
    def sortColors(self, nums: List[int]) -> None:

        # empty list
        if not nums:
            return

        l = len(nums)

        right = l-1
        left = 0
        while left < right and nums[left] == 0:
            left += 1
        while left < right and nums[right] == 2:
            right -= 1

        tmp = left
        while tmp <= right:
            if nums[tmp] == 2:
                if nums[right] == 0:
                    nums[tmp] = nums[left]
                    nums[left] = 0
                    nums[right] = 2
                    left += 1
                    right -= 1
                else:
                    nums[tmp] = nums[right]
                    nums[right] = 2
                    right -= 1

            else:
                if nums[tmp] == 0:
                    nums[tmp] = nums[left]
                    nums[left] = 0
                    left += 1
            
            while left < right and nums[left] == 0:
                left += 1
            while left < right and nums[right] == 2:
                right -= 1

            tmp = max(tmp+1, left)
        return
  1. 官方解法

在看到官方解法后,觉得自己的方法虽然时间复杂度和空间复杂度并没有特别大的劣势,但是代码不够简洁,思路不够清晰,所以又参考了官方代码改了一版答案。
官方代码的思路是也是用三个指针,分别是left、right和tmp,但是left、right需要满足的条件和我的代码的条件不同。

nums[idx<left]=0(3)nums[idx>right]=2(4) nums[idx<left] = 0\qquad (3)\\ nums[idx>right] = 2\qquad (4)
官方解法对nums[left]和nums[right]没有要求,所以就不用写那两个循环。
思路依然是将0全都移到left指针左边,2移到right指针右边。将数组从头到尾扫一遍,如果nums[tmp]为0,就将nums[left]与nums[tmp]替换,将0移到left左边,同时将left和tmp均向右移一格,如果nums[tmp]为1,那么就直接将tmp向右移一格,如果nums[tmp]为2,就将nums[right]与nums[tmp]替换,同时将right向左移一格,将2移到right右边,因为nums[right]的值没有被考察过,所以此时tmp不能向右移。
完整代码:

class Solution:
    def sortColors(self, nums: List[int]) -> None:

        # empty list
        if not nums:
            return

        l = len(nums)

        right = l-1
        left = 0
        tmp = left
        while tmp <= right:
            if nums[tmp] == 0:
                nums[tmp] = nums[left]
                nums[left] = 0
                tmp += 1
                left += 1
            elif nums[tmp] == 2:
                nums[tmp] = nums[right]
                nums[right] = 2
                right -= 1
            else:
                tmp += 1
        return
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章