领扣网算法学习笔记 -- 26

领扣网算法学习笔记

本系列的算法题目来自领扣网

数组类算法第三天

题目:删除排序数组中的重复项

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

不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

示例:

给定数组 nums = [1,1,2], 
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

解题过程:

思路:

看到这道题时,感觉很简单,直接动手写,写完测试时发现怎么做都不对,然后发现题目审错了,开始我以为只是一个数组,没有排序,需要在不使用额外空间的情况下以O(1)完成,所以我的思路是记录最后一个不相同的元素的位置,初值为最后一个元素的位置,将相同的元素与最后一个元素交换,然后记录的位置往前移一位,这样就无需遍历了。但是后面测试代码出现问题,后面审题才发现是有序的。于是思路简化,直接定义一个变量用来记录不同值的位置,然后将不同值依次从第一位赋值过去即可。

代码如下:

class Solution {
    public int removeDuplicates(int[] nums) {
        // 因为数组有序,所以重复值只能在一起,所以定义一个变量,循环遍历数组,当出现一个不同值时,数值加一
        int numdate = 1;
        for(int i=0;i<nums.length-1;i++){
            if(nums[i]!=nums[i+1]){
                nums[numdate] = nums[i+1];
                numdate++;
            }
        }
        return (numdate);
    }
}
// 用时14ms

后续思考:

审题这事不容忽视,工作中,弄清业务需求也一样,不然开发再完美,但是不符合需求,而且还浪费了时间。

领扣上面该题其他高质量范例:

class Solution {
    public int removeDuplicates(int[] nums) {
        int index = Integer.MAX_VALUE ;
        int counter = 0 ;
        for(int i=0; i<nums.length; i++){
            if(nums[i] == index) nums[i] = Integer.MAX_VALUE ;
            else {
                counter++ ;
                index = nums[i] ;
            }
        }
        Arrays.sort(nums);
        return counter ;
    }
}
// 用时10ms

自我整理:

​ 领扣上还有时间更短的示例,但是思路和我的类似,有的差不多只是变量名不同,但是执行时间就是比我的快,百思不得其解。

​ 这个例子算是与我的区别比较大的一种。

​ 我的是比较相邻的两个值是否相同,这里是当值没有变化时,位置不变,继续往后读取比较,变化后再重新赋值比较;

​ 但是这个没有对数组进行排序,后面再使用Arrays.sort进行排序的。

代码优化:

class Solution {
    public int removeDuplicates(int[] nums) {
        int numdate = 0;
        for(int i=1;i<nums.length;i++){
            if(nums[numdate]!=nums[i]){
                numdate++;
                nums[numdate] = nums[i];
            }
        }
        return (numdate+1);
    }
}
// 用时8ms

自我整理:

优化内容就不总结了,主要明白了一点,原来去数组中取指定位置的值也是需要时间的,所以这也是一个优化点。

猜你喜欢

转载自blog.csdn.net/xxydzyr/article/details/84112669