删除有序数组中的重复项
题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array/?envType=study-plan-v2&envId=top-interview-150
题目如下:
常规解法
- 使用有序的容器记录数组出现的不同值,如果已经存在直接跳过即可
- 将容器里面值对nums数组进行覆盖
- 返回容器大小
class Solution {
public int removeDuplicates(int[] nums) {
List<Integer> res = new ArrayList<>();
for (int num : nums) {
if (res.contains(num)) {
continue;
}
res.add(num);
}
for (int i = 0; i < res.size(); i++) {
nums[i] = res.get(i);
}
return res.size();
}
}
成功AC
tips:
判断容器内是否存在某个值是,使用set集合会比list集合更快。因为set集合内部是map的key-value,内部还是一个hash表,hash的查询时间复杂度是O(1),而list集合查询的时间复杂度是O(N)
使用Set集合替换后可以看到耗时减少
public int removeDuplicates(int[] nums) {
LinkedHashSet<Integer> res = new LinkedHashSet<>();
for (int num : nums) {
if (res.contains(num)) {
continue;
}
res.add(num);
}
int index = 0;
for (Integer num : res) {
nums[index++] = num;
}
return res.size();
}
如果是工作中用这种场景个人感觉就可以了,但是如果是面试的话,面试官是想考某些点,这个题目和前两篇的博客一样都是考双指针
双指针解法
这次使用双指针的解法和之前有点不太一样,之前遇到的都是从数组两边开始内收left++;right–,先看思路:
题目要求是将数组修改为前k个值为不重复的元素,并且与原数组顺序一致(这里就引导说明不是从左右两边建立索引了)因为数组有序,那么重复值的值就是挨着的,我们将遇到的第一个与left的索引值覆盖left+1位置的即可,直到right==nums.length,方法的返回值即为left + 1
为什么要进行+1 因为left的值最后一个不重复的值,索引是从0开始的,所以要进行加+1,可能有点绕,hhh
public int removeDuplicates(int[] nums) {
if (nums == null || nums.length < 2) {
// 保证代码的健壮性,可以减少很多问题
return nums.length;
}
int left = 0;
int right = 1;
while (right < nums.length) {
if (nums[left] != nums[right]) {
nums[++left] = nums[right++];
} else {
right++;
}
}
return left + 1;
}
晚安,好梦