题目
首先注意数组是有序的,那么重复的元素一定会相邻。
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
思路
这个数组是一个排序数组,那好办多了,只需要将每一个数值与它前面的数值进行比较,如果重复就不计入最终长度length就好了。还有,每一次发现一个新的元素,要把它存入数组nums[length-1]的位置【我们发现第一个元素,它的length是1,但是数组的小标是从0开始的】
代码
class Solution {
public int removeDuplicates(int[] nums) {
//判空,虽然是简单题,但是这东西我还因此wa了一次
if (nums.length==0)
return 0;
//length是最终要返回的nums数组的长度
int length=0;
int tmp=nums[0];//临时记录当前的元素
int count=0;//计算元素是否重复的计数器
for (int i=0;i<nums.length;++i)
{
if (nums[i]==tmp)//如果当前的tmp与nums[i]相等,那么count自增1
{
++count;
if (count==1)//只有第一次,也就是当前元素的数目为1的时候,才会增加返回数值的长度
{
++length;//返回数组长度加1
nums[length-1]=nums[i];//把当前的元素的值赋值给最终的nums数组
}
}
else //nums[i]!=tmp
{
tmp=nums[i];//不等于,那么出现了新的元素
count=1;
if (count==1)
{
++length;
nums[length-1]=nums[i];
}
}
}
return length;
}
}
结果
想法还是有一点欠缺,没有那种全局考虑的思维,居然忘记了测试边界用例和特殊用例,导致wa了一次。挺不应该的。而且想知道,那些排在我前面的用了内存是多少。。。太强了这群人。
官方思路
利用双指针来解题,利用一个快指针和一个慢指针,因为重复的元素一定会相邻,如果不一样了,那么就是不重复了,那么i就要加1,j是快指针,分别比较nums[j]和nums[j-1]即可得出结果。
官方代码
//双指针
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
for (int j = 1; j < nums.length; j++) {
if (nums[j] != nums[i]) {
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
}
官方结果
真的很妙,虽然内存和我的解法差不多但是这种思想,真的妙!
精选题解
思路
先判空,然后,利用双指针,如果当前值与后指针不一样,那么就出现了新的值,那么就要将后面的数值赋值给当前指针的下一个【比如第1个数值与第0个数值不同,那么就要将第1个数值赋给第0个数值的下一个数值即第一个数值,因为第0个数值本身也是存储的唯一值】
这里也就造就了一个可以优化的地方,如果说数组中所有的元素都不一样,那么,每次我们都要将原来位置赋值给自己,造成浪费,可以加个判定
代码
//双指针
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 0;
int j=1;
while (j<nums.length)//当数组没有遍历结束
{
if (nums[i]!=nums[j])//当前值与后指针的值不相等
{
nums[i+1]=nums[j];//新值赋值给当前值的下一个位置【因为当前存放的也是一个唯一值】
++i;//把左指针往右挪
}
++j;//把右指针往左挪
}
return i + 1;
}
}
改进
public int removeDuplicates(int[] nums) {
if(nums == null || nums.length == 0) return 0;
int p = 0;
int q = 1;
while(q < nums.length){
if(nums[p] != nums[q]){
//增加了这个判断,避免重复复制,浪费时间
if(q - p > 1){
nums[p + 1] = nums[q];
}
p++;
}
q++;
}
return p + 1;
}
总结:虽然这道题也不是什么难题,但是大佬的想法真的太强了!!!跪服,献上膝盖!