LC.27 移除元素 做题笔记


注: 本文是做题笔记,并不是原创题解,用于整理自己的思路,文中参考的代码都会标注出处

题目地址

LC.27 移除元素

参考题解

宫水三叶题解

思路

  • 题目要求原地修改数组,也就不能使用额外空间
  • O(n) 级别的时间复杂度

在需要遍历数组,同时保留题目要求的元素时(即 [要求/保留]逻辑) 我们往往采用双指针

双指针解法:

  • 两个指针全部放在集合的起始位置
  • 两个指针一个头一个尾
  • 两个指针一个放在起始,一个放在中点

但在题目描述中:不要求新数组中元素的顺序,也不要求数组中超出新长度之后的元素(即新长度并不一定是数组的真实长度,且新长度之后的数组是什么元素都无所谓

因此我们选用 两个指针一个头一个尾的方案,把要删除的元素直接交换到新长度之后。

代码

class Solution {
    public int removeElement(int[] nums, int val) {
        int j = nums.length - 1; //放一个指针在数组结尾
        for (int i = 0; i <= j; i++) { // 再放一个指针在数组开头
            if (nums[i] == val) {
                swap(nums, i--, j--); 
                //只有在发生交换的情况下,j指针才会前移
                //精髓的一步,i--可以避免交换之后的元素仍然为val的情况
                // 假设第一个元素就等于val,且交换后还等于val,那么i--就等于-1,但随后进入下一层循环 i++, i再次等于0,避免了数组越界
            }
        }
        return j + 1;//遍历结束的时候 j == i,数组新长度为当前下标加1
    }
    void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
}

作者:AC_OIer
链接:https://leetcode.cn/problems/remove-element/solution/shua-chuan-lc-shuang-bai-shuang-zhi-zhen-mzt8/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

代码作者: 宫水三叶

题解的精妙之处

  1. 考虑了数组越界问题
  2. 考虑了原数组长度为奇数和为偶数的情况