LeetCode高频题26. 删除有序数组中的重复项

LeetCode高频题26. 删除有序数组中的重复项

提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
在这里插入图片描述
基础知识:
【1】LeetCode高频题15:三数之和


文章目录

  • LeetCode高频题26. 删除有序数组中的重复项
    • @[TOC](文章目录)
  • 题目
  • 一、审题
  • 二、解题
  • 总结

题目

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

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

判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = […]; // 输入数组
int[] expectedNums = […]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


一、审题

示例:示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

提示:

0 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按 升序 排列


二、解题

这种题目的思想,咱们已经见过多次了

啥思想呢?
就是i与i-1不相等的时候,咱们可以收集答案
你看看这个题:
【1】LeetCode高频题15:三数之和
当时的答案怎么收集?
以a开头,那么后续的答案,就不能再以a开头了,当然i=0时,直接要了答案【因为i=0是第一个,就不会重复的】

本题也是一样的,要求不能用外部数组转移,就空间复杂度o(1)
那么显然就是要把不重复的统统移动到左边来
那只要你i和i-1处数字不相同,咱就往前挪,用index来控制结果数组的位置变化

比如index=0,最开始的话
i=0,1,直接搬移放1,index++=1
i=1,1,查i-1也是1,不搬
i=2,2,查i-1=1,不同,搬i到index=1处,然后index++=2
i=3,2,查i-1也是2,不搬
i=4,2,查i-1也是2,不搬
i=5,3,查i-1=2,不同,搬i到index=2处,然后index++=3
i=6,4,查i-1=3,不同,搬i到index=3处,然后index++=4
i=7,4,查i-1也是4,不搬
完事
LeetCode高频题26. 删除有序数组中的重复项_第1张图片

手撕代码:

        //复习:
        //那只要你i和i-1处数字不相同,咱就往前挪,用index来控制结果数组的位置变化
        public int removeDuplicatesReview(int[] nums) {
            if (nums == null || nums.length == 0) return 0;

            int index = 0;//控制新结果,后续的不管
            int N = nums.length;
            for (int i = 0; i < N; i++) {
                if (i == 0 || nums[i] != nums[i - 1]) nums[index++] = nums[i];
            }

            //最后index就是结果,咋着都会加1的
            return index;
        }

测试:

    public static void test(){
        int[] arr = {1,1,2,2,3,4,4};
        int[] arr2 = {1,1,2,2,3,4,4};
        Solution solution = new Solution();
        int len = solution.removeDuplicates(arr);
        for (int i = 0; i < len; i++) {
            System.out.print(arr[i] +" ");
        }
        System.out.println();

        len = solution.removeDuplicatesReview(arr2);
        for (int i = 0; i < len; i++) {
            System.out.print(arr2[i] +" ");
        }
    }

    public static void main(String[] args) {
        test();
    }

结果OK

1 2 3 4 
1 2 3 4 

LeetCode测试
LeetCode高频题26. 删除有序数组中的重复项_第2张图片LeetCode高频题26. 删除有序数组中的重复项_第3张图片
这个题目属于超级超级超级简单级别的了

你也可以这样写
随意,反正实现了就行

public int removeDuplicates(int[] nums) {
            if (nums == null || nums.length == 0) return 0;
            //从0位置开始搜,找不同于当前i的数,填过来,同时每次记录我数组长++
            int index = 0;//数组索引
            int i = 0;
            nums[index++] = nums[i];
            while (i < nums.length - 1){
                int j = i + 1;
                while (j < nums.length && nums[i] == nums[j]) j++;
                //当j那个数恰好不等于i
                if (j < nums.length){//j不可越界
                    nums[index++] = nums[j];
                }
                i = j;//更新位置
            }
            return index;//这就是长度了
        }

总结

提示:重要经验:

1)这种i和i-1位置数字不一样的,才有必要收集答案的思想,咱们见过多次了,熟悉了就知道在这用,不用别人说你也能手撕代码
2)反正算法题就是优先考虑时间复杂度,再考虑空间复杂度
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。

你可能感兴趣的:(大厂面试高频题之数据结构与算法,leetcode,有序数组,删除有重复元素,删除数组元素,数组元素搬移)