leetcode 双指针——283移动零

代码链接:https://github.com/xinhui1111/leetcode/blob/master/src/doublePoint.cpp
void moveZeroes(vector &nums) void moveZeroes_Official(vector& (nums))
想看最优的解法(这里的最优只是我已经会实现的最优)可以直接跳转到二、官方解法

零、题目说明

leetcode 双指针——283移动零_第1张图片
两个要求:

  1. 将零放在后面;
  2. 非零的相对位置不能变;

一、自己的解法

最开始错误的解法——遇0首尾互换,相对位置被打乱

原理
首先我是想着直接将双指针一个放在第一个位置上,一个放在最后一个位置,然后两者进行转换,遍历完整个数组。
leetcode 双指针——283移动零_第2张图片

实现代码

void moveZeroes(vector<int> &nums) {
    //这种方法把相对位置变了
    //可以从前往后进行推,遇到0就将其放在最后,并且放了之后指向最后的位置就向前移动一位
    int left{0};
    int right{static_cast<int>(nums.size()-1)};
    //前后两个指针,前面一个一步步向后移动,当遇到0就与最后的进行转换,转换了之后后面的指针也要向前移动一个,非0就向后进行移动,
    while(left<right){
        if(nums[left]==0){
            //将这个位置和最后一个位置的数进行互换
            if(nums[right]!=0){
                //进行互换
                int temp{0};
                temp=nums[left];
                nums[left]=nums[right];
                nums[right]=temp;
            }
            right--;
        }
        left++;

    }
}

优劣
放入官方代码中,检查是否正确:
leetcode 双指针——283移动零_第3张图片
可以看到是因为顺序不对,这是因为首尾互换打乱了顺序。我们拿出前面的原理图就可以看出来,因为前面没有特别留意到这里顺序被打乱了:
leetcode 双指针——283移动零_第4张图片
比如这的12就因为在最后,与第一个就换了位置,换到了第一的位置,那么就和之前的相对位置不一样了。

正确的解法——每次遇到0向前平移,效率不高

原理
为了保证相对位置不变,首先想到的最简单的办法就是遇到0的时候就把0放在最后,然后0后面的元素都向前移动一位,同时两个指针位置也要改变。
leetcode 双指针——283移动零_第5张图片
代码

void moveZeroes(vector<int> &nums) {
    int left{0};
    int right{static_cast<int>(nums.size()-1)};

    while (left<right){
        if(nums[left]==0){
            //就把left后面的全部往前移动
            for(int i=left;i<right;i++){
                nums[i]=nums[i+1];
            }
            nums[right]=0;
            right--;
        }
        else
            left++;
    }

}

优劣
将其提交,可以看到代码效率很低:
leetcode 双指针——283移动零_第6张图片

二、官方的解法

原理
将非零值一步步提到最前面,所以关键是移动右指针,遇到非零就把它换到前面,并且是以类似尾插针的方式:
leetcode 双指针——283移动零_第7张图片
代码实现

/*
 * 借鉴了官方的解法
 * 将指针放在相邻的位置,如果遇到是0的时候,就把0放在前面
 */
void moveZeroes_Official(vector<int>& (nums)){
    int left{0};
    int right{0};
    while (right<nums.size()){
        if(nums[right]){
            //将left与right进行互换
            int temp{0};
            temp=nums[left];
            nums[left]=nums[right];
            nums[right]=temp;

            left++;
        }
        right++;
    }
}

优劣
将其提交,看到效率不错:
leetcode 双指针——283移动零_第8张图片

你可能感兴趣的:(leetcode,c++,leetcode,算法,职场和发展)