6. <tag-数组和双指针(快慢针)>-lt.26-删除数组中的重复元素+lt.283-移动零

lt.26 删除数组中的重复元素

[案例需求]
在这里插入图片描述
在这里插入图片描述

[思路分析]

  1. 本道题是典型的使用快慢指针的题目;
  2. 首先给出的数组是有序的, 并且是原地对数组进行操作的, 所以我们必须要考虑用双指针解题, 而且这两个指针能够在一定程度上分别指向需要原地交换的两个数, 不是说删除吗, 为什么还会交换呢? 因为数组在底层并不是真正的删除一个元素, 而只是忽略掉这个元素的索引, 所以我们通过交换把需要访问的非重复元素放在前半段, "删除"后的元素放在后面, 只访问前半段;
  3. 再仔细读题目, 发现我们需要返回对数组去重后的非重复数组, 所以我们能够想到留一个指针去指示每次交换后的非重复数组, 而把另一个指针用来遍历整个数组;
    [代码实现]
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 移动零

[案例需求]
在这里插入图片描述

[思路分析]

  1. 为什么会想到用双指针? 一是他要求原地逆转(肯定要用到数组中两个数之间的交换), 我们肯定会需要两个游标(或者说指针)来指示每次需要交换的两个数, 二是我们从题目可知, 数组前一部分要求是不为0, 所以我们肯定需要指针来指示每次遍历时, 数组不为0的末尾的位置;
  2. 具体思路如下:
    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++;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/nmsLLCSDN/article/details/121316094