这个问题可以通过使用双指针技术来解决。我们可以使用两个指针,一个慢指针 slowRunner 用于跟踪新数组的末尾,另一个快指针 fastRunner 用于遍历数组。每当 fastRunner 遇到一个新的唯一元素时,就将其复制到 slowRunner 指向的位置,并将 slowRunner 向前移动一位。
下面是具体的实现代码:
public class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int slowRunner = 0;
for (int fastRunner = 1; fastRunner < nums.length; fastRunner++) {
// 如果当前元素与前一个元素不同,则将其复制到 slowRunner 指向的位置
if (nums[fastRunner] != nums[slowRunner]) {
slowRunner++;
nums[slowRunner] = nums[fastRunner];
}
}
// 返回唯一元素的数量
return slowRunner + 1;
}
}
解释
- 初始化:设置 slowRunner 和 fastRunner 初始值分别为 0 和 1。同时检查数组是否为空。
- 遍历数组:使用 fastRunner 来遍历数组,从第二个元素开始。
- 比较并移动:如果 fastRunner 当前指向的元素与 slowRunner 指向的元素不同,则将 fastRunner 的元素复制到 slowRunner 后面,并将 slowRunner 向前移动一位。
- 返回结果:当 fastRunner 遍历完整个数组后,slowRunner + 1 就是唯一元素的数量。
这种方法的时间复杂度为 O(n),其中 n 是数组的长度,因为每个元素只被访问一次。空间复杂度为 O(1),因为我们是在原数组上操作,没有使用额外的空间。
这种方法保证了元素的相对顺序保持一致,并且只保留了唯一的元素。