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.
自己优化后的代码:
反思改进策略:
- c++的速度是python的三到十倍。python更加适合研究,c++适合部署硬件。两种语言都要很熟练
- 注意交换后的数字,要不要纳入考虑范围。在if 和else 的流程中,就有先后顺序关系,先把数字和start替换。替换之后直接判断是否等于2,相当于在判断了交换回来的数字。后面和end交换之后,要把i--,就是交换回来的数字,还需要再检查一次
- c++,有系统自带的swap语句,不需要自己造轮子