首页 > 试题广场 >

排列颜色

[编程题]排列颜色
  • 热度指数:15788 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
现在有一个包含n个物体的数组,其中物体颜色为颜色为红色、白色或蓝色,请对这个数组进行排序,让相同颜色的物体相邻,颜色的顺序为红色,白色,蓝色。
我们用0,1,2分别代表颜色红,白,蓝
注意:
本题要求你不能使用排序库函数
扩展:
一个非常直接的解法是两步的计数排序的算法
首先:遍历一遍数组,记录0,1,2的数量,然后重写这个数组,先将0写入,再将1写入,再将2写入
你能给出一个只用一步,并且能在常数级空间复杂度解决这个问题的算法吗?
public class Solution {
    public void sortColors(int[] A) {
        if(A == null || A.length < 2)
            return;
        int l = -1;//0区的右边界
        int r = A.length;//2区的左边界
        int m = 0;//1区的右边界
        while(m < r){//当1区右边界和2区左边界相遇时停
            if(A[m] == 0){
                swap(A, ++l, m++);
            }else if(A[m] == 2){
                swap(A, m, --r);
            }else{//A[m] == 1
                m++;
            }
        }
    }
    
    public void swap(int[] arr, int i, int j){
        if(i != j){
            arr[i] = arr[i] ^ arr[j];
            arr[j] = arr[i] ^ arr[j];
            arr[i] = arr[i] ^ arr[j];
        }
    }
}

发表于 2021-09-08 21:58:06 回复(0)
class Solution {
    public void sortColors(int[] nums) {
        //首先形式上:如果是考数组的算法 双指针算是常规套路了。。这个荷兰🇳🇱国旗问题用的三指针
        //其次 本质上 也还是蛮巧妙的。
        int p0, p1, p2, tmp;
        p0 = 0;
        p1 = 0;
        p2 = nums.length - 1;

        while(p1 <= p2){
            if(nums[p1] == 0){
                //如果p1对应的元素是0 交换p0和p1对应的元素,然后向后++一位
                tmp = nums[p0];
                nums[p0++] = nums[p1];
                nums[p1++] = tmp;
            }
            else if(nums[p1] == 2){
                //交换,--
                tmp = nums[p1];
                nums[p1] = nums[p2];
                nums[p2--] = tmp;
            }
            else{
                p1++;
            }
        }
    }
}

发表于 2020-07-15 21:17:44 回复(0)
public class Solution {
    public void sortColors(int[] A) {
        int l1 = 0;
        //int l2 =  0;
        int l3 = 0;
        //创建新数组,拷贝原数组,原数组置1
        int[] a = new int[A.length];
        for(int i = 0;i<A.length;i++){
            a[i]=A[i];
            A[i]=1;
        } 
        //遍历新数组元素,遇到一个0,原数组前面的变0,遇到一个2,后面的变2
        for(int i = 0;i<a.length;i++){
            if(a[i]==0){
                A[l1]=0;
                l1++;
            }
            
            if(a[i]==2){
                A[A.length-l3-1]=2;
                l3++;
            }
        } 
        
    }
}

发表于 2020-04-21 17:35:54 回复(0)
import java.util.Arrays;

public class Solution {
    public void sortColors(int[] A) {
        int zeroIndex = 0;
        int twoIndex = A.length - 1;
        int i = 0;
        while (i <= twoIndex) {
            if (A[i] == 0) {
                swap(A, i, zeroIndex);
                zeroIndex++;
                i++;
            } else if (A[i] == 2){
                swap(A, i, twoIndex);
                twoIndex--;
            } else {
                i++;
            }
        }
    }

    private void swap(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }
}
发表于 2018-04-02 15:25:01 回复(0)
public class Solution {
    public void Swap(int A[], int i, int j)
    {
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;
    }
    public void sortColors(int[] A) {
        //开始的一定为0;最后的一定为2
        int start = 0;
        int end = A.length-1;
        for(int i=0;i<=end;i++){
            if(A[i]==0){
                Swap(A,i,start++);
            }
            if(A[i]==2){
                Swap(A,end--,i);
                //end与i交换后需要重新比较一次i
                --i;
            }
        }
    }
}


发表于 2018-02-02 22:03:05 回复(0)
public class Solution {
    public void sortColors(int[] A) {
        int length=A.length;
        if(length<2)
            return;
        int last=0;
        for(int count=0;count<3;count++)
        for(int i=last;i<length;i++){
            if(A[i]==count){
        int temp=A[last];
        A[last]=count;
        A[i]=temp;
        last++;
            }
        }
    }
}

发表于 2017-08-23 18:49:51 回复(0)
// two pass O(m+n) space void sortColors(int A[], int n) { int num0 = 0, num1 = 0, num2 = 0; for(int i = 0; i < n; i++) { if (A[i] == 0) ++num0; else if (A[i] == 1) ++num1; else if (A[i] == 2) ++num2;
    } for(int i = 0; i < num0; ++i) A[i] = 0; for(int i = 0; i < num1; ++i) A[num0+i] = 1; for(int i = 0; i < num2; ++i) A[num0+num1+i] = 2;
} // one pass in place solution void sortColors(int A[], int n) { int n0 = -1, n1 = -1, n2 = -1; for (int i = 0; i < n; ++i) { if (A[i] == 0) 
        {
            A[++n2] = 2; A[++n1] = 1; A[++n0] = 0;
        } else if (A[i] == 1) 
        {
            A[++n2] = 2; A[++n1] = 1;
        } else if (A[i] == 2) 
        {
            A[++n2] = 2;
        }
    }
} // one pass in place solution void sortColors(int A[], int n) { int j = 0, k = n - 1; for (int i = 0; i <= k; ++i){ if (A[i] == 0 && i != j)
            swap(A[i--], A[j++]); else if (A[i] == 2 && i != k)
            swap(A[i--], A[k--]);
    }
} // one pass in place solution void sortColors(int A[], int n) { int j = 0, k = n-1; for (int i=0; i <= k; i++) { if (A[i] == 0)
            swap(A[i], A[j++]); else if (A[i] == 2)
            swap(A[i--], A[k--]);
    }
}

发表于 2017-03-12 11:58:12 回复(0)
public class Solution {
   public void sortColors(int[] A) {
		int begin = 0;
		int end = A.length - 1;
		int cur = 0;
		while (cur <= end) {
			// 所有的0放到数组前边
			if(A[cur] == 0) {
				A[cur] = A[begin] ^ A[cur] ^ (A[begin] = A[cur]);
				begin ++ ;
				cur ++ ;
			// 所有2放到数组后边
			} else if(A[cur] == 2) {
				A[cur] = A[end] ^ A[cur] ^ (A[end] = A[cur]);
				end -- ;
			} else cur ++ ;
		}
	}
}
编辑于 2016-12-03 00:57:45 回复(0)