【初级算法】删除排序数组中的重复项

题目:

一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

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

 

思路:

首先还是最基础的解答思路,数组已经排序,则重复值都会连在一起,故按顺序遍历数组,如果当前元素与下一元素相同,则删除下一节点,数组整体向前移动,否则继续遍历

解答:

class Solution {
    public int removeDuplicates(int[] nums) {
        int i = 0;
        int end  = nums.length - 1;
        while (i < end) {
            if (nums[i] == nums[i+1]) {
                for (int j = i+1; j < end; j++) {
                    nums[j] = nums[j+1];
                }
                end--;
            } else {
                i++;
            }
        }
        return end + 1;
    }
}

 

结果与反思:

时间与空间都有极大浪费,需要考虑优化方案。

首先大部分的时间都浪费在数组删除元素上,考虑到题目要求原地修改,且不关注去重长度后的数组部分内容,可以不对数组进行前移调整,只将正确的值放在正确的位置最后通过裁剪达到效果。

优化思路:

使用双指针结构。

右指针始终往右移动,起到遍历功能,查到正确的值。

左指针默认不移动,与右指针值不相同时向右移动,代表去重后元素的正确位置。

如果右指针指向的值不等于左指针指向的值,那么左指针往右移一步,然后再把右指针指向的值赋给左指针;否则右指针继续右移,直到遍历结束。

优化答案:

class Solution {
    public int removeDuplicates(int[] nums) {
        int left = 0;
        for (int right=1; right<nums.length; right++) {
            if (nums[left] != nums[right]) {
                nums[++left] = nums[right];
            }
        }
        return left + 1;
    }
}

 

posted @ 2022-01-06 10:27  ProbablyTrue  阅读(24)  评论(0编辑  收藏  举报