zoukankan      html  css  js  c++  java
  • 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语句,不需要自己造轮子
  • 相关阅读:
    CNZZ公告:近期无法获取百度关键词
    怎样注册uber司机 如何注册uber司机 最新详细攻略
    Uber司机一周体验记:成单率仅57%
    Uber司机手机终端问答篇
    Uber 司机有话说:你以为当个 Uber 司机很轻松?大错特错!
    每门编程语言修复了什么
    let区别(关于racket和r5rs)
    Bloom Filter
    静态作用域与动态作用域
    C 语言的可变参数表函数的设计
  • 原文地址:https://www.cnblogs.com/captain-dl/p/10980032.html
Copyright © 2011-2022 走看看