数据结构与算法分析笔记与总结(java实现)--链表8:对排序链表删除重复结点问题
来源:互联网 发布:painter是什么软件 编辑:程序博客网 时间:2024/06/07 05:54
思路:所谓删除结点node只需要将node前面结点的next指针直接指向node结点的下一个结点即可,不需要将node置null或者将node的next属性置为null,因为被删除结点由于不再被上一个结点引用,就会成为不可达的死对象从而会被GC自动回收。
这里关键是如何判断重复结点,并且将指针指向下一个不重复的结点;判断连续的重复很复杂:
这道题目较复杂,关键是对于几种特殊类型的全面考虑,即便捷情况的考虑:
pnext为null怎么办?
如果是pcur的第一个pnext指针为null,表示为1233445这种情况,即最后一个结点没有重复;即pcur是没有重复的结点,且是最后一个结点,此时对应情形①。于是将pcur连接到retainedNode后面然后返回dummy链表即可。
如果是在pnext对重复的多个结点进行移动时出现pnext为null,表示为12334555这种情况,即最后的结点重复,此时对应情形②,由于不会再有新的结点出现了,而最后一个结点又不是单独的结点,因此所有工作已经结束了,可以直接结束循环返回dummy链表,如果不及时返回会进入情况①的else模块中,导致retainedNode又被附上了pcur的值,而pcur实际上是重复值!
情况③是普通的情况,即用来寻找不重复的结点。即要有一个指针pnext来遍历判断后面的几个结点是否是重复的,如果有重复就向下移动,直到有不重复的结点,将它作为新的pcur,并将它连接到retainedNode链表上面。
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
// 该方法用来删除链表中重复的结点,最终返回的链表中没有重复的结点1223445-->135
public ListNodedeleteDuplication(ListNode pHead) {
// 特殊的输入
if (pHead ==null) return null;
// 由于需要构造返回一条新的链表,因此使用固定技巧
ListNodedummy = new ListNode(-1);
// 保留下来的结点组成的链表
ListNoderetainedNode = dummy;
// 当前正在判断是否重复的结点
ListNodepcur = pHead;
// 找准确循环条件究竟是什么,这里是对每个当前结点进行遍历:先pcur!=null,再求出pcur的next结点
while (pcur !=null) {
// 当前结点之后的结点,需要逐个与pcur进行比较
ListNodepnext = pcur.next;
/**
* pcur之后的值与他相同,pcur必然是重复结点,还需要将重复部分全部遍历完 共有几种情况:
1.pnext是null,表示pcur是最后一个结点;
2.pnext!=null但是pcur.val ==pnext.val表示下一个结点与pcur重复;
3.pnext!=null但是pcur的下一个值与他不同,表示pcur是一个不重复的点;
每种情况要分别处理。
*/
if (pnext!= null && pcur.val == pnext.val) {
while(pnext != null && pcur.val == pnext.val) {
//pnext指针不断向下移动
pnext= pnext.next; //情况③
}
//当pnext指针不再往下移动时有两种情况:1.pnext为null;2.此时pnext终于不再是 重复值了,是一个新的值,分别处理。
//如果pnext为null,那么表示是尾部相同的数例如123444,应该立即结束循环返回, 否则会进入12333445的else模块,这两种情形是不同的。
if(pnext != null) {
pcur= pnext;
pnext= pcur.next;
}else { //情况②
returndummy.next;
}
} else if(pnext != null && pcur.val != pnext.val) {
//如果pcur之后的值与pcur就不同,那么说明pcur是唯一的,不重复,需要保留
//特别注意:要把pcur结点连接到retainedNode时,需要先将pcur后面的结点关系切断,否则如果pcur是retainedNode上面的最后一个结点,那么会把pcur后面所跟的结点全部带到retainedNode链表中来;例如12233455可能会得到1455,因为当4被连接到retainedNode上面时会将55也带着。
pcur.next = null;
retainedNode.next= pcur;
retainedNode= retainedNode.next;
//此时也需要向下推进,判断下一个结点是否重复
pcur= pnext;
pnext= pcur.next;
} else {
// 即此时pnext==null,说明pcur已经是最后一个结点了,这个结点必然是不重复的结点,即最后一个结点是一个单独的结点,例如12333445 //情形①
retainedNode.next= pcur;
retainedNode= retainedNode.next;
returndummy.next;
}
}
return dummy.next;
}}
牛人简洁代码:再理解
public static ListNode deleteDuplication(ListNode pHead) {
ListNode first = newListNode(-1);//设置一个trick
first.next = pHead;
ListNode p = pHead;
ListNode last = first;
while (p != null &&p.next != null) {
if (p.val == p.next.val){
int val = p.val;
while (p!=null&&p.val == val)
p = p.next;
last.next = p;
} else {
last = p;
p = p.next;
}
}
return first.next;
}
- 数据结构与算法分析笔记与总结(java实现)--链表8:对排序链表删除重复结点问题
- 数据结构与算法分析笔记与总结(java实现)--链表14:删除链表中所有指定值结点问题
- 数据结构与算法分析笔记与总结(java实现)--链表10:输入某个结点删除单向链表中的该结点
- 数据结构与算法分析笔记与总结(java实现)--链表6:两个链表找公共结点问题
- 数据结构与算法分析笔记与总结(java实现)--链表7:含环链表找环入口结点问题
- 数据结构与算法分析笔记与总结(java实现)--链表9:有序环形链表中插入新结点问题
- 数据结构与算法分析笔记与总结(java实现)--链表13:每k个结点逆序问题
- 数据结构与算法分析笔记与总结(java实现)--二叉树8:寻找错误结点练习题
- 数据结构与算法分析笔记与总结(java实现)--链表3:链表反转问题
- 数据结构与算法分析笔记与总结(java实现)--链表4:单调链表合并问题
- 数据结构与算法分析笔记与总结(java实现)--链表15:链表回文判断问题
- 数据结构与算法分析笔记与总结(java实现)--数组8:数组中重复的数字
- 数据结构与算法分析笔记与总结(java实现)--排序8:小范围排序练习题
- 数据结构与算法分析笔记与总结(java实现)--链表问题面试笔试注意点
- 数据结构与算法分析笔记与总结(java实现)--链表2:倒数第k个结点问题(k从1开始)
- 数据结构与算法分析笔记与总结(java实现)--链表5:复杂链表的复制问题
- 数据结构与算法分析笔记与总结(java实现)--链表12:打印两个升序链表公共值问题
- 数据结构与算法分析笔记与总结(java实现)--排序算法的分析
- C++ Qt Game Tutorial 1 - Drawing the Player (rectangle)
- NOI 2014 魔法森林 LCT
- 推背图第四十三象
- 判断是鼠标拖拽还是点击
- CCF 2015 3-2 数字排序
- 数据结构与算法分析笔记与总结(java实现)--链表8:对排序链表删除重复结点问题
- bzoj2683&&1176 CDQ分治
- 服务器安装dedecms是提示GD及mysql不支持解决方案
- 括号配对问题
- 12.2 Spring整合myBatis
- valgrind详解
- 二叉树
- HDU4405 水概率
- 移动端绝对定位无法隐藏的问题解决方案