leetcode 283.移动零
题目描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
解题思路
采用尽可能少的操作次数。可以把当前的零值元素改成下一个非零值的元素,并且用一个变量记录有多少个非零值,然后以此变量作为下标,把后面的元素全部置为零,就可以完成零元素的后移。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int nonZeroIndex = 0;
for(int i=0; i<nums.size(); i++){
// 把零元素用非零值代替
if(nums[i] != 0){
nums[nonZeroIndex] = nums[i];
nonZeroIndex++;
}
}
// 把nonZeroIndex以后的元素全部置为零。
for(int i=nonZeroIndex; i<nums.size(); i++){
nums[i] = 0;
}
}
};
同样的方法,还有一种优化的方法
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int index = 0;
for(int i=0; i<nums.size(); i++){
// 如果是非零元素,那么就是保持自身不变,如果是零,把零元素不断的和非零元素交换,
if(nums[i] != 0){
int temp = nums[index];
nums[index] = nums[i];
nums[i] = temp;
index++;
}
}
}
};
这是一种相对而言操作次数较多的写法,从数组的两端开始同时处理,首先确定右端非零元素的下标,再从左侧开始查找零元素,找到零元素就往后移。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int left = 0;
int right = nums.size()-1;
// 寻找右侧非零元素的下标,同时右侧下标不等于零,若是零,表示所有的元素都是零。
while(nums[right] == 0 && right > 0){
right--;
}
// 从左侧开始查找非零元素
while(left < right){
// 如果非零,左侧下标加一
if(nums[left] != 0){
left++;
continue;
}
// 如果是零元素,通过交换元素的方式,把零元素移到右侧。
for(int i=left; i<right; i++){
int temp = nums[i];
nums[i] = nums[i+1];
nums[i+1] = temp;
}
right--;
}
}
};
欢迎大家关注我的个人公众号,同样的也是和该博客账号一样,专注分享技术问题,我们一起学习进步