在做leetcode第26题时,删除掉一个数组中的重复元素nums[k],我第一时间 想到的是将下标k之后的元素全部前移,利用一个for循环,覆盖掉自己的前一个元素。这样子需要进行几轮,似乎还需要用到三个指针,非常麻烦。
在看题解时,我得到了一种非常简练的解法:删除数组中的重复项,相当于把数组中不相重复的元素全部挪到数组的左侧。 至于右侧剩余的是什么,我想我们没必要考虑,反正最后需要返回的是最终不相重复的数组的长度,返回了这个长度,作为遍历数组的上界,那么右侧永远是访问不到的。在这种算法思想下,删除数组中的重复项变得非常简单。
这里我们使用两个指针来完成。值得注意的是,在数组中,我们定义两个整型变量p、q来指示下标,以作为所谓的指针。
具体代码如下
(注意:方法的返回值是删除重复项后的数组长度,由于方法体中对数组的引用进行操作,数组本身已经发生变化,所以主函数中直接输出nums下标0~length-1的元素即是最终的结果数组)
public static int removeDuplicates(int[] nums){
/*
* 原地删除数组中的重复项,本质上是将数组中不重复的元素移动到数组左侧
* 注意:整型数组中无法使用引用,指针使用下标来实现
*/
if(nums == null || nums.length == 0){
return 0;
}
int p = 0;//慢指针
int q = 1;//快指针
int length = nums.length;
while(q < length){
if(nums[p] == nums[q]){
q++;
}
else{
nums[p+1] = nums[q];
p++;
q++;
}
}
return p+1;
}
主方法如下:
public static void main(String[] args) {
int[] a = {0,0,1,1,1,2,2,3,3,4};
int len = removeDuplicates(a);
System.out.println(len);
for(int i=0;i<len;i++){
System.out.print(a[i]+" ");
}
}