题目
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
解
也想到了交换,但是想到的是麻烦的
遍历,如果当前是0,那么while找到之后1,交换,找不到结束。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n = nums.size();
for(int i = 0 ;i < n;i++)
{
if(!nums[i]){
int j = i + 1;
while(1)
{
if(j >= n) return;
if(nums[j])
{
swap(nums[i],nums[j]);
break;
}
j++;
}
}
}
}
};
用迭代器,先删0,后加0
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int k = 0;
for(auto it = nums.begin();it<nums.end();)
{
if(*it == 0)
{
nums.erase(it);
k++;
}else{
it++;
}
}
for(int i =0 ;i<k;i++){
nums.push_back(0);
}
}
};
官解:快速排序的思想,双指针
妙:
- 交换次数虽然差不多
- 但是遍历次数少了,我的交换while会出现重复判断当前元素是不是0的多余,比如
00011
的第三个0会经过两次while判断。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int n = nums.size(), left = 0, right = 0;
while (right < n) {
if (nums[right]) {
swap(nums[left], nums[right]);
left++;
}
right++;
}
}
};
感想
看来还是基础的排序没有吃透,里面的交换思想没有融入思考体系。