删除排序链表中重复元素的方法
时间:2022-07-22
本文章向大家介绍删除排序链表中重复元素的方法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
链表的操作非常常见,也是面试中经常会被问道的问题。对于链表重复元素的删除,有两个变体,现在总结如下。 链表代码如下:
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
1.删除重复元素,所有元素只保留一次。
* @description 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
* 示例 1:
* 输入: 1->1->2
* 输出: 1->2
* 示例 2:
* 输入: 1->1->2->3->3
* 输出: 1->2->3
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list
这个问题的解法非常简单,只需要定义一个指针然后while循环即可。
public ListNode deleteDuplicates(ListNode head) {
ListNode cur = head;
while (null!=cur&&null!=cur.next){
if(cur.val == cur.next.val){
if(null != cur.next.next){
cur.next = cur.next.next;
}else {
cur.next = null;
}
}else {
cur = cur.next;
}
}
return head;
}
定义一个指针cur,然后循环判断cur.value和cur.next.value,如果相等,那么就将后面重复元素移除。如果不等,则指针后移。
2.删除全部重复的元素,只保留没有重复的元素。
*@description
* 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
* 示例 1:
* 输入: 1->2->3->3->4->4->5
* 输出: 1->2->5
* 示例 2:
* 输入: 1->1->1->2->3
* 输出: 2->3
* 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii
本文需要重点关注的是这个变体,因为问题1的解法很简单。没什么特别的。但是加上了将全部重复的数字都去除这个条件之后,难度瞬间增加了不少。你需要考虑两个问题:
- 如果链表头就是重复的数字怎么办
- 如何移动比较链表,删除元素?
第一,对于表头重复的问题,那么最简单的办法就是在表头添加一个元素,加入链表。之后在链表遍历完之后,返回哨兵的next。这是一个非常好的办法,简直是以后解决链表类问题的套路之一。
ListNode cur = new ListNode(0);
cur.next = head;
head = cur;
仅仅三行代码就搞定了。 第二,对于如何移动比较的问题,此时发现,用一个指针无论如何也无法实现题目的需求了。此时看到了参考文档中的三指针法。现在将文章中的内容发下来: 除了哨兵之外,需要定义一个left和一个right两个指针。
先用right和right下一个元素比较,如果相等,则left移动。之后循环判断left和right两个指针是否指向同一个元素。如果相等,则说明没有相同的元素。哨兵cur向后移动。反之,则说明存在相同的元素,哨兵则将当前next指针指向right.next,将重复元素都删除。完整算法如下:
public ListNode deleteDuplicates(ListNode head) {
ListNode cur = new ListNode(0);
cur.next = head;
head = cur;
ListNode left,right;
while (null!=cur&&null!=cur.next){
left = cur.next;
right = cur.next;
while (null!=right.next&&right.next.val==left.val){
right = right.next;
}
if(right == left){
cur = cur.next;
}else {
cur.next = right.next;
}
}
return head.next;
}
三指针法,也是一个经典的算法。在后续面链表相关问题的时候,又是一个新套路。
- 域名Deskbike.com刚注册没多久就以五位数结拍
- 一起Polyfill系列:Function.prototype.bind的四个阶段
- winform实现拼图游戏
- 一起Polyfill系列:让Date识别ISO 8601日期时间格式
- Oracle 监听器无法启动(TNS-12537,TNS-12560,TNS-00507)
- Javascript Prototypes之旅(A Plain English Guide to JavaScript Prototypes译文)
- Python补充03 Python内置函数清单
- 不懂JQuery的孩子:自封装Ajax函数
- .Net魔法堂:史上最全的ActiveX开发教程——ActiveX与JS间交互篇
- 飓风“桑迪”路径图的制作
- 根据标准word模板生成word文档类库(开源)
- Oracle 监听器无法启动(TNS-12555,TNS-12560,TNS-00525)
- Python补充02 Python小技巧
- 四则运算核心算法(开源)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 简易数据分析(七):Web Scraper 抓取表格、分页器翻页数据
- codeforces 1327C(构造)
- zabbix分布式及高可用
- Angular单元测试的spyOn使用一例
- SQL-JOIN全解析
- Node.js上传单文件和多文件的一些示例博客和源代码
- ES6中的箭头函数=>
- 22 个让 React 开发更高效更有趣的工具
- JavaScript中==和===的区别
- 解决:打包SpringBoot项目成jar包后,其他的项目无法引入jar包中的对象
- 【分享】MPSoC R5引导4个A53和两个R5的应用程序的例子
- 【分享】MPSoC交叉编译例子
- JSON.stringify() 的 5 个秘密特性
- Kyverno - Kubernetes 原生策略管理引擎
- 你不知道的 Vue 单元测试(6000字实战单元测试)