携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
概述
数组算是一个并不复杂的数据结构,但就是这个,面试官就能在面试过程中考察出很多东西来。例如经典的排序问题,二分搜索,滑动窗口等等,都是在数组这种最基础等数据结构中处理问题的。
我们做数组类算法问题的时候,常常需要定义一个变量,明确该变量的意义,并不停的维护这个变量,也需要特别注意初始值
和边界
问题。
题目
给你一个有序数组 nums
,请你 原地
删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地
修改输入数组 并在使用 额外空间的条件下完成。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以 「引用」 方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。
输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。
提示
1 <= nums.length <= 3 * 10^4
-10^4 <= nums[i] <= 10^4
nums
已按升序排列
代码实现
该题的解题思路与《删除有序数组中的重复项》类似,不同的地方在于本题支持保留两个相同的元素,比前面的这题多了一个,那么我们在处理逻辑上就需要做一点小小的改动,具体实现请参考代码。
class Solution {
public int removeDuplicates(int[] nums) {
// 边界处理
int n = nums.length;
if (n <= 2) {
return n;
}
// 定义左右两个指针分别指向索引值为2的地方,因为前面最多可以有两个相同元素,所以不用比较判断
int left = 2, right = 2;
while (right < n) {
// 判断当前元素与前两位的元素是否相同,只有当元素不相同的时候,才需要保存该元素
if (nums[left - 2] != nums[right]) {
// 保存当前元素,并移动left指针到下一个位置
nums[left] = nums[right];
++left;
}
++right;
}
return left;
}
}