怒刷力扣(删除有序数组中的重复项)

简介: 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次,返回删除后数组的新长度。

删除有序数组中的重复项

WangScaler: 一个用心创作的作者。

声明:才疏学浅,如有错误,恳请指正。

题目

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

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

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

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

分析

初步思考

这个题的目的就是把数组中重复的元素删除。为了避免数组的移动,我们可以创建一个新的数组来存放我们去重的元素。但是在java中,一是创建数组要先分配大小、而是题目要求我们不要使用额外的空间,你必须在 原地 修改输入数组 。那么第一种方法是不可行的,其次数组是有下标的,也就意味着删除元素,那么后边的所有元素就需要往前移动,才能满足我们的目的。

继续思考

那么这个题的核心就是我们要怎么避免全部移动而且还能实现我们的目标了。

值得注意的是,题目要求我们只需要保证前k个条件符合要求就行。那么我们只需要保证数组的前k个元素就可以了,无需管k+1之后的元素,也就是说我们并不需要全部移动后边的元素。遍历完后边的值是什么我们无需考虑,我们只需要把新的元素从原有重复的元素替换出去就可以了。

首先我们遍历数组,用两个指针分别标记我们遍历完的位置(即我们已经处理完毕的数组的最后一个位置)和遍历的位置的指针。

如果遍历的元素和第一个指针指向的元素的前一个不一样,那么把新的值赋予给目标值且把两个指针都后移。如果一样,前一个指针不动,后一个指针一直遍历到元素不一样为止。

答案

public static int removeDuplicates(int[] nums) {
        int target = 1;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] != nums[target - 1]) {
                nums[target] = nums[i];
                target += 1;
            }
        }
        return target;
    }

遍历完target就是数组去重之后的元素个数。nums的前target个元素就是我们去重之后的结果。

复杂度

  • 时间复杂度:O(n),其中 n 是数组的长度。只需要将数组的元素遍历一遍即可。
  • 空间复杂度:O(1)。只需要一个target记录去重之后的位置和遍历的指针i即可。

总结

这个题有个图就很好理解了。

例如nums = [0,0,1,1,1,2,2,3,3,4]

  • 第一个元素我们无需看他的值,他一定是去重后数组的第一个值。
  • 第一次遍历,我们比较红色指向元素的值和绿色指向位置的前一个元素的值,如果一样只需要把红色指针后移

image.png

  • 第二次遍历,我们比较红色指向元素的值和绿色指向位置的前一个元素的值,如果不一样我们把target指向的值修改为红色指针指向的值,然后两个指针均向后移

image.png

  • 第三、四次遍历,我们比较红色指向元素的值和绿色指向位置的前一个元素的值,如果一样只需要把红色指针后移

image.png

image.png

  • 第五次遍历,我们比较红色指向元素的值和绿色指向位置的前一个元素的值,如果不一样我们把target指向的值修改为红色指针指向的值,然后两个指针均向后移

image.png

  • 重复以上过程,最后的结果

image.png

都来了,点个赞再走呗!

关注WangScaler,祝你升职、加薪、不提桶!

目录
相关文章
|
1月前
leetCode(删除有序数组中的重复项)
如何在不使用额外空间的情况下,通过双指针法原地删除有序数组中的重复项。
33 2
|
3月前
|
存储 Java API
LeetCode------合并两个有序数组(4)【数组】
这篇文章介绍了LeetCode上的"合并两个有序数组"问题,并提供了三种解法:第一种是使用Java的Arrays.sort()方法直接对合并后的数组进行排序;第二种是使用辅助数组和双指针技术进行合并;第三种则是从后向前的双指针方法,避免了使用额外的辅助数组。
LeetCode------合并两个有序数组(4)【数组】
|
1月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
19 4
|
1月前
【LeetCode 48】108.将有序数组转换为二叉搜索树
【LeetCode 48】108.将有序数组转换为二叉搜索树
38 0
|
3月前
|
算法
LeetCode第26题删除有序数组中的重复项
这篇文章介绍了LeetCode第26题"删除有序数组中的重复项"的解题方法,通过使用双指针技巧,高效地去除数组中的相邻重复元素。
LeetCode第26题删除有序数组中的重复项
|
3月前
|
算法
LeetCode第80题删除有序数组中的重复项 II
文章介绍了LeetCode第80题"删除有序数组中的重复项 II"的解法,利用双指针技术在O(1)空间复杂度内原地删除重复元素,并总结了双指针技术在处理有序数组问题中的应用。
LeetCode第80题删除有序数组中的重复项 II
|
3月前
|
Python
【Leetcode刷题Python】977. 有序数组的平方
解决LeetCode "有序数组的平方" 问题的方法:使用Python内置的快速排序、直接插入排序(但会超时)和双指针技术,并给出了每种方法的Python实现代码。
21 1
【Leetcode刷题Python】977. 有序数组的平方
|
3月前
|
算法
LeetCode第88题合并两个有序数组
文章分享了LeetCode第88题"合并两个有序数组"的解法,通过从后向前的合并策略避免了数组元素的前移,使用三个指针高效地完成了合并过程。
|
3月前
|
Python
【Leetcode刷题Python】108. 将有序数组转换为二叉搜索树
LeetCode上108号问题"将有序数组转换为二叉搜索树"的Python实现,通过递归选取数组中间值作为根节点,构建高度平衡的二叉搜索树。
25 2
|
3月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
54 0