1. 数组 - 做好初始定义
做数组类算法问题的时候,我们常常需要定义一个变量,明确该变量的定义,并且在书写整个逻辑的时候,要不停的维护住这个变量的意义。也特别需要注意初始值和边界的问题。
做数组类题目的通用步骤
- 先将 分区的定义 写在代码中
- 初始化变量的值时保证三个区间都是空区间
- 遍历时不停的维护 分区的定义
1. 移动零 (力扣 283)
题目 : https://leetcode.cn/leetbook/read/all-about-array/x9rh8e/
解法 (快慢指针法)
使用快慢指针, 快指针用来扫描, 慢指针用来指向可覆盖的位置。
慢指针指向当前已经处理好的序列的尾部, 快指针指向待处理序列的头部。快指针不断向右移动, 每次快指针指向非零数, 则将快慢指针对应的数交换, 同时慢指针右移。
注意到以下性质:
- 慢指针左边均为非零数;
- 快指针左边直到左指针处均为零。
- 快指针右边都是待处理数。
左边界 --------------- 慢指针 ----------------- 快指针 ---------------- 右边界
保留的元素(非0) 不保留的元素 (0) 待处理的元素
因此每次交换, 都是将慢指针的零与快指针的非零数交换, 且非零数的相对顺序并未改变。
2. 移除元素 (力扣 27)
题目 : https://leetcode.cn/leetbook/read/all-about-array/x9p1iv/
解法一 (快慢指针法)
解法同 移动零, 只要把前等于 val 的值用后面不等于 val 的值覆盖就可以, 而不需要交换这两个值。有如下性质 :
- 只需要保证 左指针左边均为非 val 值即可
- 不用保证右指针左边到左指针都为 val 值
解法二 (左右指针法)
- 左指针找等于 val 的元素, 右指针找不等于 val 的元素
- 如果左指针的当前元素等于 val :
- 那么让右指针的元素覆盖左指针的元素
- 如果右指针的元素覆盖完了左指针的元素还是 val, 那么右指针继续往左移动
- 如果左指针的当前元素不等于 val, 那么左指针继续往右移动
3. 删除排序数组中的重复项 (力扣 26)
题目 : https://leetcode.cn/leetbook/read/all-about-array/x9a60t/
解法
如果快指针的值 和 快指针前面相邻的值不一样, 那么就用慢指针保存快指针的值
4. 删除排序数组中的重复项2 (力扣 80)
题目 : https://leetcode.cn/leetbook/read/all-about-array/x9nivs/
解法
-
nums[fast]
表示待检查的第一个元素 -
nums[slow − 1]
为所有应该被保留的元素的最后一个 -
nums[slow − 2]
为所有被保留的元素的倒数第二个
因为本题要求相同元素最多出现两次而非一次, 所以需要检查上上个应该被保留的元素 nums[slow − 2]
是否和当前待检查元素 nums[fast]
相同, 如果不同, 那么执行 nums[slow] = nums[fast];
保留元素。
网友评论