Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
Note:
- You must do this in-place without making a copy of the array.
- Minimize the total number of operations.
将一个数组中的0全部放到最后,其他的按照原来的顺序排到前面去,不能拷贝数组。
刚开始我是想法就是用一个zero来记录数组中的最后0元素的下标,用num记录非0元素的下标。如果num比zero大的话,说明后面的一个非0的需要放到前面来,让其交换即可,然后让zero寻找下一个非0位置。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int zero = -1;//表示最后一个0的下标
int num = 0;//表示非0的下标
for(int i=0; i < nums.size() ;i++) {
if(nums[i] != 0) {//如果此时不等于0,先用num记录下来此刻的坐标
//cout << "此刻不等于0:" << i << endl;
num = i;
}
if(zero == -1 && nums[i] == 0) {
//cout << "找到数组中的第一个0下标:" << i << endl;
zero = i;
}
if(zero != -1) {
if(num > zero) {//如果num大于zero,说明后面有一个非0,此刻需要交换位置了,并且让zero等于自后一个0的下标
//cout << "发生交换的两个下标为,非0:" << num << ",0:" << zero << endl;
swap(nums[zero],nums[num]);
//cout << "交换完之后zero下标的元素为:" << nums[zero] << ",num下标的元素为:" << nums[num] << endl;
while(nums[zero] != 0) {
//cout << "这里的zero不等于0,所以需要向后查找,此刻zero为:" << zero << endl;
zero++;
//i++;
}
if(zero>=nums.size()) {//说明已经完成了
break;
}
}
}
}
//for(int i=0;i<nums.size();i++) {
//cout << nums[i] << ",";
//}
}
};
不过这种的效率不高,后来看了看靠前的做法,发现没必要记录非0和0的下标。如果发现有非0元素直接判断是否需要交换就可以了。同样的也是两个标志i和j,两个都从零开始,一个i循环自增,如果发现此刻的元素非0,则判断当前的坐标i和另一个坐标j是否相等,相等的话说明此刻j也是处于非0位置的,就让j向后移动一位。不相等的话j一定是处于0的位置的,发生交换即可。
其中只有一点需要解释,为什么i和j不相等的话,j一定处于0位置。
假设数组是这样的:[1,2,0,0,5]。
刚开始i和j都为0,使用i开始遍历:
i = 0,发现此刻i的位置上非0,则判断此刻i和j是否相等,发现相等则说明j也是处于非0元素,就让它向后移动一位,j=1。
i = 1,此刻非0,判断i和j相等,说明j处于非0元素,则向后移动一位,j = 2。
i = 2,此刻为0,不进行计算,直接向后移动,而此刻的j就处于0位置。
i = 3,向后移动。
i = 4,此刻非0,i位置上的与j位置上的进行交换。
说白了,如果当前元素非0,那么i和j都共同的向后移动。如果当前的是0,仅仅i向后移动,所以j就停留在了0的位置。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
for(int i=0,j=0;i<nums.size();i++) {
if(nums[i]) {//如果此时不等于0,进行计算
if(i!=j) {//相等的话说明j此刻也是处于一个非0位置
swap(nums[i],nums[j]);
}
j++;//如果发生交换了需要加一,如果不交换也需要加一
}
}
//for(int i=0;i<nums.size();i++) {
//cout << nums[i] << ",";
//}
}
};