• leetcode[75] sort colors


    给定一个数组,有0,1,2三个数,把数组排好序。不能直接用sort。

    策略一:

    简单的思路,扫描两次,第一次记录0,1,2的个数,第二次重写数组。

    class Solution {
    public:
        void sortColors(int A[], int n) {
            if(n < 2) return ;
            int n0 = 0, n1 = 0, n2 = 0;
            vector<int> ans(n);
            for (int j = 0; j < n; j++)
            {
                if (A[j] == 0) n0++;
                else if (A[j] == 1) n1++;
                else n2++;
            }
            int i = 0;
            while(i < n0) {A[i] = 0;i++;}
            while(i < n0 + n1) {A[i] = 1;i++;}
            while(i < n0 + n1 + n2) {A[i] = 2;i++;}
            return ;
        }
    };

    但,要求只扫描一次,常数空间。

    策略二:

    定义一个left,一个right

    1. 遇到1,left++

    2. 遇到2,和right位置换

    3. 遇到0,往前和第一个非零数字换,left++

    class Solution {
    public:
        void sortColors(int A[], int n) {
            int left = 0, right = n -1;
            while(left <= right)
            {
                if (A[left] == 0)
                {
                    int index = left - 1;
                    while(index >= 0 && A[index] != 0) index--; // 这个算扫描一次吗?
                    if (index < 0)
                        swap(A[0], A[left]);
                    else
                        swap(A[index+1], A[left]);
                    left++;
                }
                else if (A[left] == 1)
                    ++left;
                else if (A[left] == 2)
                {
                    swap(A[left], A[right]);
                    right--;
                }
            }
        }
    };

    策略三:

    借助于快速排序的partition思想,以1为枢纽元对数组进行划分,使0在数组的左边,2在数组的右边,1在数组的中间。

    class Solution {
    public:
        void sortColors(int A[], int n) {
            //zeroEnd是放0那部分的尾部索引,twoEnd是放2那部分的首部索引
            //碰到0放到zeroEnd+1处,碰到2放到twoEnd-1处,碰到1指针后移
            int zeroEnd = -1, twoBegin = n, i = 0;
            while(i < twoBegin)
            {
                if(A[i] == 0 && i != ++zeroEnd)
                    swap(A[zeroEnd], A[i]);
                else if(A[i] == 2 && i != --twoBegin)
                    swap(A[twoBegin], A[i]);
                else
                    i++;
            }
        }
    };

     2015/03/31:

    class Solution {
    public:
        void sortColors(int A[], int n) {
            if(n <= 1) return;
            int start = 0, end = n - 1;
            int i = 0;
            while(i <= end){
                if(A[i] == 0 && i != start){
                    swap(A, start++, i);
                }else if(A[i] == 2 && i != end){
                    swap(A, i, end--);
                }else ++i;
            }
        }
    private:
        void swap(int A[], int i, int j){
            int temp = A[i];
            A[i] = A[j];
            A[j] = temp;
        }
    };
  • 相关阅读:
    Linux基础知识
    c语言依赖倒转
    ios的认识
    ios数据的基本类型和流程控制
    JavaScript 创建 自定义对象
    《大道至简》读后感
    总结
    字符串转换成整型并求和
    《大道之简》第二章
    SQL Server 2008 数据库自动备份
  • 原文地址:https://www.cnblogs.com/higerzhang/p/4100200.html
Copyright © 2020-2023  润新知