Leetcode26——删除有序数组中的重复项(双指针法)
Leetcode26——删除有序数组中的重复项(双指针法)
1. 题目简述
给你一个升序排列的数组 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];
}
如果所有断言都通过,那么您的题解将被 通过。
示例 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 已按 升序 排列
(原题链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/)
2. 暴力破解法
最简单的想法应该是使用暴力破解法,即使用两层循环,如遇到下标为i + 1的元素与下标为i的元素相同,则将后面的元素依次覆盖到到前一个位置,否则自增内层变量j。此外,用一个变量来记录数组在覆盖元素后的新长度,即初始值为数组长,每次覆盖该变量减少1。
虽然思路非常简单,但是有一个容易出错的地方:这里内层最好是使用while循环,这与我们覆盖的方式有关。覆盖之后,内层循环变量不能加1!否则会越过一个元素哦!也就是说无法完全消除重复的元素。
class Solution {
public int removeDuplicates(int[] nums) {
int newLength = nums.length;
int j;
for (int i = 0; i < newLength; i++) {
j = i + 1;
while (j < newLength) {
if (nums[i] == nums[j]) {
for (int k = j + 1; k < newLength; k++) {
nums[k-1] = nums[k];
}
newLength--;
}
else
j++;
}
}
return newLength;
}
}
代码分析
这个思路非常直接,但是代价是数组去重时会移动大量的元素,这造成了相当程度上资源的浪费。
3. 双指针法
该如何解决暴力解法的问题呢?可见我们要尽可能降低数组元素移动的次数(也就是数组的覆盖去重操作)。
让我们仔细阅读一下题目,我们只要保证处理后的数组前k个元素是不重复且相对顺序不变的即可,我们可以拿一个整型变量i来表示处理后数组各个位置的数组下标,拿另一个整型变量j来表示目前正在遍历的元素。(免费图床质量太差,有空自己搭一个吧)
过程的描述(仅举部分例子):
从初始状态来看,nums[0]为0,nums[1]为1,两者不同,没有重复,故i++,j从i的下一位继续开始。
num[1] = 2,num[2] = 2,重复!但此时i不要动,检查其他重复元素,直到出现不同元素为止。
j++,num[3] = 3,不同,故i++,j从i的下一位继续开始。
重复以上过程,直到j指针到数组末端
class Solution {
public int removeDuplicates(int[] nums) {
int i = 0, j = 1;
while (j < nums.length) {
if (nums[i] != nums[j]) {
i++;
nums[i] = nums[j];
}
else
j++;
}
return i + 1; // 返回的是无重复数组长哦
}
}
代码分析
由于在运行的过程中,每个元素最多被访问两次,最坏情况时间复杂度为O(n),这是一个非常大的提升了!这也是我自己第一次悟出来双指针法!纪念一下!
Leetcode26——删除有序数组中的重复项(双指针法)的更多相关文章
- 【python】Leetcode每日一题-删除有序数组中的重复项
[python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...
- [LeetCode每日一题]80. 删除有序数组中的重复项 II
[LeetCode每日一题]80. 删除有序数组中的重复项 II 问题 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不要使用额外 ...
- 【python】Leetcode每日一题-删除有序数组中的重复项2
[python]Leetcode每日一题-删除有序数组中的重复项2 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不 ...
- 删除有序数组中的重复项II
题目描述 给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素最多出现两次,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组 并在使用O(1)额外空间的条件下 ...
- 【LeetCode】80. 删除有序数组中的重复项 II
80. 删除有序数组中的重复项 II 知识点:数组:排序:双指针: 题目描述 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不要使 ...
- 【LeetCode】26. 删除有序数组中的重复项
26. 删除有序数组中的重复项 知识点:数组:排序:双指针: 题目描述 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度. 不要使用额外的 ...
- 80. 删除有序数组中的重复项 II
题目 给你一个有序数组 nums ,请你原地删除重复出现的元素(不需要考虑数组中超出新长度后面的元素),使每个元素最多出现两次 ,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入 ...
- 4.19——数组双指针——26. 删除有序数组中的重复项 & 27. 删除有序数组中的重复项II & 80. 删除有序数组中的重复项 II
第一次做到数组双指针的题目是80: 因为python的List是可以用以下代码来删除元素的: del List[index] 所以当时的我直接用了暴力删除第三个重复元素的做法,大概代码如下: n = ...
- [LeetCode]26.删除有序数组中的重复项(Java)
原题地址: remove-duplicates-from-sorted-array 题目描述: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的 ...
随机推荐
- CSS/CSS3语法新特性笔记
CSS层叠样式表 三大特性 层叠性:相同的样式会覆盖 继承性:属性可向下继承 优先级:范围越小权重越高 选择器 基础选择器 标签选择器 1 body { 2 color:#fff; 3 } 类选择器 ...
- 洛谷训练P1008(循环+暴力)
1 #include<stdio.h> 2 #include<string.h> 3 int a[10]; 4 int main(){ 5 for (int x=123;x&l ...
- MongoDB数据库的下载安装及配置方法
MongoDB安装与配置步骤 MongoDB数据库之安装篇 # 1 下载MongoDB数据库 1.打开浏览器,登录"https://www.mongodb.com/try/download/ ...
- vue项目npm run dev报错events.js:160 throw er; // Unhandled 'error' event listen EADDRINUSE :::8002
出错情况,如下图: 报错原因: listen EADDRINUSE :::8002 意思是当前8002端口被占用 解决办法: 一:简单粗暴:关掉可能影响的相关程序,重新执行启动. 二: 1.Win+R ...
- 前端好用API之getBoundingClientRect
前情 在前端开发需求中,经常需要获取元素的尺寸位置相关的属性,以往的做法是调用不同api获取相关属性的. getBoundingClientRect介绍 getBoundingClientRect() ...
- 【Azure API 管理】使用APIM进行XML内容读取时遇见的诡异错误 Expression evaluation failed. Object reference not set to an instance of an object.
问题描述 使用APIM,在 Inbound 中对请求的Body内容进行解析.客户端请求所传递的Request Body为XML格式,需要从Request Body中解析出多个(Element)节点值, ...
- Windows原理深入学习系列-访问控制列表-关于安全描述符的补充
这是[信安成长计划]的第 20 篇文章 0x00 目录 0x01 安全描述符的结构 0x02 两个结构的不同点 0x03 真正的查询方案 0x04 参考文章 0x01 安全描述符的结构 在上一篇文章中 ...
- WPF-ListView单元格设置文字换行
第2-6行 1 <ListView Name="HumidifyEventLog" Style="{StaticResource ListViewStyle}&qu ...
- 基于idea做java程序的本地k8s调试-skaffold(二)
上一篇讲完了java代码发到本机minikube中run,这篇来讲讲minkube中进行debug(idea下) 话说,上篇是把pigx基础infra微服务都发到了minikube中,这些微服务是ru ...
- 29 面向对象编程 static 关键字
补充:static 代码 // static public class Student{ private static int age; // 静态的变量 多线程 private double sco ...