6. <tag-数组和双指针(快慢针)>-lt.26- 删除有序数组中的重复项+lt.283-移动零 2.7
lt.26 删除数组中的重复元素
[案例需求]
 
 
[思路分析]
- 本道题是典型的使用快慢指针的题目;
- 首先给出的数组是有序的, 并且是原地对数组进行操作的, 所以我们必须要考虑用双指针解题, 而且这两个指针能够在一定程度上分别指向需要原地交换的两个数, 不是说删除吗, 为什么还会交换呢? 因为数组在底层并不是真正的删除一个元素, 而只是忽略掉这个元素的索引, 所以我们通过交换把需要访问的非重复元素放在前半段, "删除"后的元素放在后面, 只访问前半段;
- 再仔细读题目, 发现我们需要返回对数组去重后的非重复数组, 所以我们能够想到留一个指针去指示每次交换后的非重复数组, 而把另一个指针用来遍历整个数组;
 [代码实现]
class Solution {
    public int removeDuplicates(int[] nums) {
        //有序数组, 理应考虑到双指针, 至于何种双指针, 细读题目
        // 定义左右指针L,R. L始终指向非重复的数组最后一位, R是遍历原数组,
        // 发现与L的元素不同, 立即移动L指针, 并交换L,R对应的元素
        // L 与 R元素相同, 则R继续向后移动一位
        int L = 0;
        int R = 1;
        if(nums.length < 1) return 0;
        while(R < nums.length){
            
            if(nums[L] != nums[R]){
                L++;
                nums[L] = nums[R];
            }
            R++;
        }
        return L+1;
    }
}
lt. 283 移动零
[案例需求]
 
[思路分析]
- 为什么会想到用双指针? 一是他要求原地逆转(肯定要用到数组中两个数之间的交换), 我们肯定会需要两个游标(或者说指针)来指示每次需要交换的两个数, 二是我们从题目可知, 数组前一部分要求是不为0, 所以我们肯定需要指针来指示每次遍历时, 数组不为0的末尾的位置;
- 具体思路如下:
 1. 定义两个指针, 快慢指针, slow用于标记每次遍历之后, 数组中不为0部分的最后一个数, 初值应设为 -1, 为什么 -1? 因为我们每次交换两个数时, 我们需要先移动 slow指针, 这个时候slow指针才会指向0哦;
 2. 快指针 fast, 用于遍历整个数组, 初值为0,
 - 每当遇到不为0的数时, 便要在移动一位慢指针后, 与快指针交换.
 - 每当遇到为0的数, 变直接后移一位即可;
[代码实现]
class Solution {
    public void moveZeroes(int[] nums) {
        //移动0 , 原地移动, 快慢指针
        int slow = -1;
        int fast = 0;
        int temp = 0;
        
        while(fast < nums.length){
            if(nums[fast] != 0){
                slow++;
                temp = nums[slow];
                nums[slow] = nums[fast];
                nums[fast] = temp;
            }
            fast++;
        }
    }
}
[思路二, 一次遍历, 不使用交换方法]
- 还是用双指针, 因为数组中不为0的数的个数肯定是要小于为0的数的个数的, 而题目只是要求我们把0放在后面, 所以我们可以先用fast遍历一次数组, 然后用slow从0-> slow, 用fast遇到的不为0的数去覆盖0->slow的所有数
- 这样的话, fast一趟遍历下来, 不为0的数都集中到了数组的前部分, 也就是从0–>slow的区间内, 然后再把slow–> nums.length的数置为0即可,
- 相比于思路一, 不用交换0和非0元素, 降低了时间复杂度.
class Solution {
    public void moveZeroes(int[] nums) {
         //fast先循环一趟, 把不为0的数全部赋值给slow
        int slow = 0;
        int len = nums.length;
        if(len < 2)return;
        for(int fast = 0; fast < len; fast++){
            if(nums[fast] != 0){
                nums[slow] = nums[fast];
                ++slow;
            }
        }
        for(int i = slow; i < len; i++){
            nums[i] = 0;
        }
    }
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号