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++;
}
}
}