75. Sort Colors

题目来源

LeetCode 75. Sort Colors

自我感觉难度/真实难度:

写题时间时长: 1 hours

题意:

把一个数组中的数字,把0放在最左边,然后数字2放在最右边
荷兰棋问题,对应于三颜色(red ,wight ,bule)
 

分析:

采用双索引,一头一尾。另外一个index遍历一遍数组就可以了,遇到0就和start换,遇到2的就和end换。注意换回来之后,一定要检查换回来的数字,不能直接跳过

 

自己的代码:

c++ 4ms

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int red = 0, blue = (int)nums.size() - 1;
        for (int i = 0; i <= blue; ++i) {
            if (nums[i] == 0) {
                swap(nums[i], nums[red++]);
            } else if (nums[i] == 2) {
                swap(nums[i--], nums[blue--]);         //注意这里i--,如果发生了替换,需要检查替换后的数字
            } 
        }
    }
};

python 40ms

from collections import defaultdict
class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n=len(nums)
        start,end=0,n-1
        for i in range(n):
            while nums[i]==2 and i<=end:
                nums[i],nums[end]=nums[end],nums[i]
                end-=1
            while nums[i]==0 and i>=start:
                nums[i],nums[start]=nums[start],nums[i]
                start+=1
        return 
        

代码效率/结果:

优秀代码:

c++


class Solution {
public:
    void sortColors(vector<int>& nums) {
        
        int i =0;
        int j = i+1;
        int k = nums.size()-1;
        
        while (true){
            while(i < nums.size() && nums[i] == 0) i++;
            while(k >= 0 && nums[k] == 2) k--;
            
            if (i >= k || i >= nums.size() || k < 0) return;
            
            if (nums[i] == 2) {
                nums[i] = nums[k];
                nums[k] = 2;
                k--;
            }

            else if (nums[k] == 0) {
                nums[k] = nums[i];
                nums[i] = 0;
                i++;
            }
            else {
                bool swapped = false;
                for (int j = i; j<=k; j++){
                    if (nums[j] == 1)
                        continue;
                    swapped = true;
                    if (nums[j] == 0) {
                        nums[j] = nums[i];
                        nums[i++] = 0;
                    }

                    if (nums[j] == 2) {
                        nums[j] = nums[k];
                        nums[k--] = 2;
                    }
                }
                
                if (!swapped){
                    return;
                }
            }
            
        }
        
        
    }
};
       

平移的方法

//平移的方法
class Solution {
public:
    void sortColors(vector<int>& A){
        int n=A.size();
        int i = -1;
        int j = -1;
        int k = -1;
        for(int p = 0; p < n; p ++)
        {
            //根据第i个数字,挪动0~i-1串。
            if(A[p] == 0)
            {
                A[++k] = 2;    //2往后挪
                A[++j] = 1;    //1往后挪
                A[++i] = 0;    //0往后挪
            }
            else if(A[p] == 1)
            {
                A[++k] = 2;
                A[++j] = 1;
            }
            else
                A[++k] = 2;
        }

    }
};
//两次遍历,记录个数。再造数组的方法
class Solution {
public:
    void sortColors(int A[], int n) {
        int i = 0;
        int j = 0;
        int k = 0;
        for(int p = 0; p < n; p ++)
        {
            if(A[p] == 0)
            {
                i ++;
            }
            else if(A[p] == 1)
            {
                j ++;
            }
            else
                k ++;
        }

        for(int p = 0; p < n; p ++)
        {
            if(p < i)
                A[p] = 0;
            else if(p >= i && p < i + j)
                A[p] = 1;
            else
                A[p] = 2;
        }
    }
};

参考资料:平移方法来源

代码效率/结果:
Runtime: 4 ms, faster than 91.35% of C++ online submissions for Sort Colors.
Memory Usage: 8.5 MB, less than 62.51% of C++ online submissions for Sort Colors.

自己优化后的代码:


 

反思改进策略:

  1. c++的速度是python的三到十倍。python更加适合研究,c++适合部署硬件。两种语言都要很熟练
  2. 注意交换后的数字,要不要纳入考虑范围。在if 和else 的流程中,就有先后顺序关系,先把数字和start替换。替换之后直接判断是否等于2,相当于在判断了交换回来的数字。后面和end交换之后,要把i--,就是交换回来的数字,还需要再检查一次
  3. c++,有系统自带的swap语句,不需要自己造轮子
posted @ 2019-06-05 15:46  dgi  阅读(152)  评论(0编辑  收藏  举报