每日算法 | 26.删除有序数组中的重复项
例题:26.删除有序数组中的重复项
题目描述:
给你一个 非严格递增排列 的数组
nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回nums
中唯一元素的个数。考虑
nums
的唯一元素的数量为k
,你需要做以下事情确保你的题解可以被通过:更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。返回
k
。
这一题一开始我想的是创建一个堆栈,然后遍历数组,将不重复的元素压入堆栈中。之后在将数组不重复的数反向出栈到数组中,就能得到无重复项的有序数组了。
但是题目要求 原地 删除重复出现的元素,这就意味着要求在数组中进行操作。在看了思路之后就理解了其中的原理,我们来先看代码:
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) {
return 0;
}
int s = 0, f = 0;
while (f < nums.length) {
if (nums[f] != nums[s]) {
s++;
nums[s] = nums[f];
}
f++;
}
return s + 1;
}
}
这个解法的思路是:设置两个值当做数组的索引,一个移动比另一个快。这样做就可以轻松地达到在遍历有序数组的过程中又能进行一定的操作。就如解法中一样,用快的那个值做的索引与慢的作比较,这样就能判断是否重复(因为是有序数组,所以慢的索引的数组内的值一定小于等于快的,不用担心有什么其他情况发生)。
这题用的主要是双指针的思路,也有非双指针的思路
非双指针:
class Solution {
public int removeDuplicates(int[] nums) {
int current = nums[0];
int count = 1;
for (int i = 1; i < nums.length; i++) {
if (nums[i] == current) {
continue;
}
nums[count++] = nums[i];
current = nums[i];
}
return count;
}
}
其实也是利用了有序数组的特性,不同即 计数+1,然后将当前比较的值作为下一次被比较的值进行下一次的是否重复的比较。
还有一点就是因为这题只需要返回删除后数组的新长度,不需要记录下来删除重复项之后的数组,所以难度简单了一些,也就不用想那么复杂。(虽然本来就就是简单题)
评论(0)