zoukankan      html  css  js  c++  java
  • LeetCode75:颜色分类与荷兰旗算法

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

    此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

    示例:

    输入: [2,0,2,1,1,0]
    输出: [0,0,1,1,2,2]

    先看这个题目,这个题目不仅仅是一个排序的问题,它的特点在于数组中的元素是固定的3个0,1,2,也就是说我们可以利用这个特性来优化一般性的排序

    由于数组中只有0,1,2,因此最后排序完成后一定是0在前,2在后,1在中间。

    如果我们使用三个指针left,right与cur。left一直指向0的后开区间,right指向2的前开区间,也就是说[0,left)间全为0,(right,nums.size()-1]间全为2。当cur为0时,交换left与cur的值,并将0区间的下限left右移;当cur=2时,交换right与cur的值,并将right左移。

    现在唯一的问题在于循环这个过程中left,right,cur的加减问题。

    现在假设cur已经领先于left:

    首先对于left来说:

    如果left为2,那么在之前cur遍历到这个2时已经将这个2交换到2区间了,也就是说left指向的值只可能是1(如果left指向的是0,则left应该在当前left的右边)。

    其次对于right来说:

    cur与right交换后,right原来的值可能是0,可能是1,也可能是2。

    因此:

    cur=0时,交换cur与left的值,并left++,且cur++;  cur++的目的是因为left指的值一定是1,因此交换后cur当前为1,cur=1既不用向前交换也不用向后交换,因此cur在交换后要自增一次。

    cur=2时,交换cur与right的值,并right--,但此时cur不能自加了。  这里cur不能自加是因为,right原来指向的值可能是0,1,2。假如是1,当然可以自加,但如果是0或2,则自加后跳过了这个值,等价于没有对这个交换前的right的值进行排序,因此不能cur++。

    class Solution {
    public:
        void sortColors(vector<int>& nums) {
    		if(nums.empty())
    			return;
    		int l=0;
    		int r=nums.size()-1;
    		int cur=0;
    		while(cur<=r&&l<nums.size()&&r>=0)
    		{
    			if(nums[cur]==0)
    			{
    				swap(nums[l],nums[cur]);
    				l++;
    				cur++;
    				continue;
    			}
    			if(nums[cur]==2)
    			{
    				swap(nums[r],nums[cur]);
    				r--;
    				continue;
    			}
    			cur++;
    		}
        }
    };
    

      

      

  • 相关阅读:
    XPOSED优秀模块列表 禁用输入法自动弹出
    XPOSED优秀模块列表 XLog
    XPOSED优秀模块列表 有自己的方向
    XPOSED优秀模块列表 WiFiPwd
    XPOSED优秀模块列表 宏/文本扩展
    XPOSED优秀模块列表 基本键盘记录器
    XPOSED优秀模块列表 屏幕过滤器
    XPOSED优秀模块列表 Play 商店修复
    XPOSED优秀模块列表 自动安装程序
    XPOSED优秀模块列表 屏幕关闭动画
  • 原文地址:https://www.cnblogs.com/lxy-xf/p/11314054.html
Copyright © 2011-2022 走看看