每一秒钟的时间都值得铭记

0%

LeetCode:删除有序数组中的重复项

题目

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

审题

这道题的重点有两个:

1、nums 是一个有序数组。

基于第一点,我们可以明白,一个指针从数组一侧移动到另一侧,一旦指针所指向的元素的值和上一个指针指向的元素的值不相等,那么该指针后面的所有元素都不会与该指针前面的元素相等,因为该数组是一个有序数组。

2、不能使用额外的内存空间,原地删除元素。

基于第二点,我们明白我们不能真正的删除元素,或者将元素移动到其他数组中,这也就意味着,我们只能在原数组中进行元素的移动,所以题目中的原地删除,本质上就是对数组元素的移动,从而达到一种“伪删除”的目的。

思路

1、在数组上设置两个指针,指针 i 初始指向 0 位索引,指针 j 初始指向 1 位索引。

2、我们向后移动 j 指针,如果 j 指向的元素不等于 i 指向的元素,我们就将 j 指针指向的元素复制到 i + 1 的索引位置上去。

3、向后移动 j 指针,直到 j 指针指向数组最后一位元素。

4、返回 i 指针指向的元素的索引 + 1,即为不重复元素的长度。

实现

实现一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int removeDuplicates(int[] nums) {
int i = 0, j = 1;
while (j < nums.length) {
if (nums[i] != nums[j]) {
swap(nums, ++i, j);
}
j++;
}
return i + 1;
}

public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}

实现二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int removeDuplicates(int[] nums) {
int i = 0;
for (int j = 1; j < nums.length; j++) {
if (nums[i] != nums[j]) {
swap(nums, ++i, j);
}
}
return i + 1;
}

public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}

结果

解答成功:
执行耗时:1 ms,击败了82.38% 的Java用户
内存消耗:39.9 MB,击败了95.36% 的Java用户

坚持原创技术分享,您的支持将鼓励我继续创作!
-------------这是我的底线^_^-------------