Leetcode——26.删除数组中的重复元素

题目

首先注意数组是有序的,那么重复的元素一定会相邻。

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 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;
}

总结:虽然这道题也不是什么难题,但是大佬的想法真的太强了!!!跪服,献上膝盖!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值