leetcode hot 100

75. 颜色分类

题目描述

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

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

注意:

不能使用代码库中的排序函数来解决这道题。

示例:

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

进阶:

一个直观的解决方案是使用计数排序的两趟扫描算法。
首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
你能想出一个仅使用常数空间的一趟扫描算法吗?

思路一:不借助计数排序,但是需要两次遍历

思路和交换0很像,也是使用一个下标指向下个0应该存放的位置,另一个指针碰到0后把这个0放到正确的位置即可,但是这里有3个数,分别是0, 1, 2, 所以应该遍历两遍,第一遍把所有0都放到最前面,第二遍把所有2放在最后面

 1 class Solution {
 2     public void sortColors(int[] nums) {
 3         int len = nums.length;
 4         int next = 0;
 5         // 把所有的0移到最前面
 6         for(int i = 0; i < len; i++){
 7             if(nums[i] == 0){
 8                 int temp = nums[next];
 9                 nums[next++] = nums[i];
10                 nums[i] = temp;
11             }
12         }
13 
14         // 把所有的2移到最后面
15         next = len - 1;
16         for(int i = len - 1; i >= 0; i--){
17             if(nums[i] == 2){
18                 int temp = nums[next];
19                 nums[next--] = nums[i];
20                 nums[i] = temp;
21             }
22         }
23     }
24 }
leetcode 执行用时:0 ms > 100.00%, 内存消耗:37.3 MB > 54.12%

复杂度分析:

时间复杂度:分别正序和倒序遍历了一次数组,所以时间复杂度为O(2n)
空间复杂度:O(1)

思路二:双指针 + 一次遍历

其实就是思路一的一个改进版

分别使用一个指针 p0 指向下个0的应该放置的位置,使用一个p2 指向下个 2 应该放置的位置。另一个指针 i 从前往后扫描,碰到 0 就和 p0所指的元素进行交换,然后p0 指针后移,碰到 2 就和 p2 所指元素进行交换,p2--, 但是这时 i 不能前移,因为不能确定nums[i]和 nums[p2]进行交换后,如果是0的话需要和nums[p0]交换,所以需要下轮继续判断nums[i]

 1 class Solution {
 2     public void sortColors(int[] nums) {
 3         int len = nums.length;
 4         
 5         int p0 = 0, p2 = len - 1;
 6         for(int i = 0; i <= p2; i++){
 7             if(nums[i] == 2){
 8                 // 因为不能确定nums[p2]是什么,如果是0的话需要和nums[p0]交换,所以需要下轮继续判断nums[i]
 9                 nums[i--] = nums[p2];   
10                 nums[p2--] = 2;
11             }else if(nums[i] == 0){
12                 nums[i] = nums[p0];
13                 nums[p0++] = 0;
14             }
15         }
16     }
17 }

leetcode 执行用时:0 ms > 100.00%, 内存消耗:37.3 MB > 64.88%

复杂度分析:

时间复杂度:只遍历了一遍数组,所以时间复杂度为O(n)

空间复杂度:O(1)

原文地址:https://www.cnblogs.com/hi3254014978/p/13804805.html