【双指针_复写零_C++】

题目解析
复写零

给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

[1,0,2,3,0,4,5,0]
[1,0,0,2,3,0,0,4]

算法原理

双指针算法
先根据“异地操作”,然后优化为双指针下的“就地”操作

【双指针_复写零_C++】_第1张图片

需要从后向前操作

【双指针_复写零_C++】_第2张图片
【双指针_复写零_C++】_第3张图片

1.先找到最后一个需要“复写”的数
	使用双指针算法
		1 先去判断cur位置的值
		2 决定dest向后移动一步或者两步
		3 判断一下dest是否已经到了结束位置
		4 如果没有到结束位置那么cur++
2.需要“从后向前”完成复写操作

【双指针_复写零_C++】_第4张图片
【双指针_复写零_C++】_第5张图片

但是会存在特殊案例:[1 0 2 3 0 4]
dest出现越界现象

【双指针_复写零_C++】_第6张图片
【双指针_复写零_C++】_第7张图片

所以说需要处理一下边界情况:
因为越界问题肯定是0导致的
需要把n-1位置的元素值修改为0
然后让dest向前移动两步,cur向前移动一步

【双指针_复写零_C++】_第8张图片
【双指针_复写零_C++】_第9张图片

编写代码

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
        //先去找到cur的位置
        int cur = 0;
        int dest = -1;
        int n = arr.size();

        while(cur<n){
            if(arr[cur]){
                dest++;
            }else{
                dest+=2;
            }
            
            if(dest>=(n-1)){
                break;
            }
            
            cur++;
        }
        //然后需要处理一下边界问题
        if(dest == n){
            arr[n-1] = arr[cur];
            dest-=2;
            cur--; 
        }
        while(cur>=0){
            if(arr[cur]){
                arr[dest--] = arr[cur--];
            }else{
                arr[dest--] = arr[cur];//0
                arr[dest--] = arr[cur];//0
                cur--;
            }
        }

    }
};

你可能感兴趣的:(双指针算法,c++,开发语言)