当前位置: 首页 > news >正文

力扣面试经典算法150题:删除有序数组中的重复项 II

删除有序数组中的重复项 II

今天的题目是力扣面试经典150题中的数组的中等难度题: 删除有序数组中的重复项 II

题目链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii/description/?envType=study-plan-v2&envId=top-interview-150

题目描述

给定一个排序好的数组 nums,请原地删除重复出现的元素,使得每个元素最多出现两次,并返回删除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

  • 示例:
    • 输入:
      nums = [1,1,1,2,2,3]
    • 输出:
      [1,1,2,2,3], 新长度为 5
    • 输入:
      nums = [0,0,1,1,1,1,2,3,3]
    • 输出:
      [0,0,1,1,2,3,3], 新长度为 7

题目分析

题目要求我们删除一个已排序数组中的重复元素,使得每个元素最多出现两次。我们需要在原地修改数组,并且只能使用常数级别的额外空间。

重点注意的地方是已排序的数组,因为已排序的数组,有需要原数组操作比较,我们可以优先考虑一下双指针法进行求解。在移出重复元素的简单难度中也分析过。只不过我们需要考虑得到是之前移出到只有一个元素,现在保留两个,那么我们指针的间距和起始位置也要修改。

解题思路

直接考虑双指针法,需要注意的就是两个指针的作用及起始位置。

双指针法:

  1. 特殊情况长度不足的直接返回。
  2. 定义一个慢指针,用于去重后的数组指针,指针大小为2,因为作为有序数组,前两个元素可以直接放入到结果数组中。
  3. 定义一个快指针,对数组进行循环,并且从索引2开始进行,因为有序数组,前两个一定是符合要求的元素。
  4. 当前数组的元素(快指针)与结果数组(慢指针)下标前两个位置的元素进行比较。如果值不相同,说明这个元素需要放到结果数组中去,同时因为放入结果数组,慢指针的值需要加1。如果相等跳过无需处理。

最后输出慢指针的值,就是结果数组的长度。

实际算法代码

下面是通过以上分析使用双指针法的 Java 实现:

public class RemoveDuplicatesII {public static void main(String[] args) {RemoveDuplicatesII solution = new RemoveDuplicatesII();// 示例数据int[] nums = {1, 1, 1, 2, 2, 3};// 调用删除重复项的方法int newLength = solution.removeDuplicatesFastSlow(nums);// 输出结果System.out.println("New length : " + newLength);}/*** 删除有序数组中的重复项 II:双指针法(快慢指针)** @param nums 排序好的数组* @return 删除重复项后的数组新长度*/public int removeDuplicatesFastSlow(int[] nums) {if (nums.length <= 2) {return nums.length;}int slow = 2;for (int fast = 2; fast < nums.length; fast++) {if (nums[fast] != nums[slow - 2]) {nums[slow] = nums[fast];slow++;}}return slow;}
}

结果

执行函数,测试通过:

在这里插入图片描述

提交到力扣,测试也通过:

在这里插入图片描述

总结

在对有序数组的问题解决中,双指针法是非常实用的。目前为止已经用了好几次了。所以熟练掌握双指针法,对于数组方面的算法问题的解决会有很大帮助。

中等难度第一题,搞定!!!

感觉还行,加油!!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java - IDEA开发
  • MySQL中处理JSON数据:大数据分析的新方向,详解与示例
  • 17. 合并两个dataframe
  • 微电网控制器是什么?微电网中央控制器|微电网协调控制器|微电网控制系统图|Micon2505微网中央控制器方案介绍
  • 汽车免拆诊断案例 | 2013款北京现代悦动车发动机偶尔无法起动
  • adb查看当前运行的应用的包名和Activity(模拟器也可以)
  • C++适配windows和linux下网络编程TCP简单案例
  • 通过共享目录上传后门
  • 学习Flutter时需要了解的背景知识
  • 实现将docx转成PDF
  • django中的MESSAGE组件
  • 支持S/MIME证书的邮件客户端有哪些?
  • 【Java学习】Stream流详解
  • 短视频SDK解决方案,降低行业开发门槛
  • pytorch实现单层线性回归模型
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Java反射-动态类加载和重新加载
  • Joomla 2.x, 3.x useful code cheatsheet
  • PHP变量
  • python 学习笔记 - Queue Pipes,进程间通讯
  • Rancher-k8s加速安装文档
  • Vue 重置组件到初始状态
  • 翻译--Thinking in React
  • 高程读书笔记 第六章 面向对象程序设计
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 扑朔迷离的属性和特性【彻底弄清】
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 如何优雅地使用 Sublime Text
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 用简单代码看卷积组块发展
  • (Python) SOAP Web Service (HTTP POST)
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (七)理解angular中的module和injector,即依赖注入
  • (十三)Flink SQL
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转) Face-Resources
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET BackgroundWorker
  • .net core 6 集成和使用 mongodb
  • .Net(C#)自定义WinForm控件之小结篇
  • .Net插件开发开源框架
  • .Net的C#语言取月份数值对应的MonthName值
  • @Autowired和@Resource装配
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [ 数据结构 - C++] AVL树原理及实现
  • [8-27]正则表达式、扩展表达式以及相关实战
  • [Android] Binder 里的 Service 和 Interface 分别是什么
  • [Angular 基础] - 表单:响应式表单
  • [asp.net core]project.json(2)
  • [BZOJ 3680]吊打XXX(模拟退火)
  • [C++]——继承 深继承
  • [CakePHP] 在Controller中使用Helper
  • [CISCN 2023 初赛]go_session