剑指offer——删除链表中重复的结点(好题!)
2017-07-04 22:17
309 查看
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
思路:
需要删掉所有重复的节点。首先,题目已经告诉我们这是一个排序的链表,因此如果节点有重复,比如4,那么4的重复节点一定都排在一起。所以,可以通过遍历一次链表,就把所有重复节点删除。
不重复节点的特点,它和自己前后的节点都不一样。第一个满足这个条件的节点是新链表的头结点。
测试用例:
{1,1,1,1,1,1,2}
对应输出应该为:
{2}
你的输出为:
{}
没有考虑最后一个节点的特殊情况。
另一种解法(头结点的设置技巧,判断不重复节点的技巧)
同样是设置头结点(自己写的,逻辑稍微清楚一些)
递归
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
思路:
需要删掉所有重复的节点。首先,题目已经告诉我们这是一个排序的链表,因此如果节点有重复,比如4,那么4的重复节点一定都排在一起。所以,可以通过遍历一次链表,就把所有重复节点删除。
不重复节点的特点,它和自己前后的节点都不一样。第一个满足这个条件的节点是新链表的头结点。
测试用例:
{1,1,1,1,1,1,2}
对应输出应该为:
{2}
你的输出为:
{}
没有考虑最后一个节点的特殊情况。
public class Solution { public ListNode deleteDuplication(ListNode pHead) { if(pHead==null) // 链表是空 return null; if(pHead.next==null) // 链表只有一个节点 return pHead; boolean Head = false; //是否找到了新的头结点 ListNode newHead = null; // 新的头结点 ListNode temp = null; // 新链表的最后一个节点 if(pHead.next.val!=pHead.val){ // 原头结点即为新头结点的情况,分开考虑比较简洁 Head = true; newHead = pHead; temp = pHead; } ListNode pBefore = pHead; ListNode pNow = pHead.next; ListNode pNext = pHead.next.next; while(pNext!=null){ if(pNow.val!=pBefore.val&&pNow.val!=pNext.val){ 4000 if(Head==false){ Head = true; newHead = pNow; temp = pNow; } else{ temp.next = pNow; temp = pNow; } } pBefore = pNow; pNow = pNext; pNext = pNow.next; } if(temp!=null&&pNow.val!=temp.val&&pNow.val!=pBefore.val){ // 考虑最后一个节点 temp.next = pNow; temp = pNow; } else if(temp==null&&pBefore.val!=pNow.val) // 除了最后一个节点,其他节点都重复的情况 newHead = pNow; if(temp!=null){ temp.next = null; // 最后把temp(即新链表最后一个节点)的next设置为null } return newHead; } }
另一种解法(头结点的设置技巧,判断不重复节点的技巧)
public class Solution { public ListNode deleteDuplication(ListNode pHead) { ListNode first = new ListNode(-1);//设置一个trick first.next = pHead; // 先令first.next = PHead ,针对PHead是null或者链表只有一个节点的情况,也可以返回正确值 //新建一个头节点解决了头节点就是重复值的麻烦! ListNode p = pHead; ListNode last = first; // 新链表的最后一个节点 while (p != null && p.next != null) { if (p.val == p.next.val) { // 如果p的val和它下一个节点的val相等,说明这一定是一个重复节点 int val = p.val; while (p!= null&&p.val == val) p = p.next; // 把所有的重复节点都找出来 last.next = p; // 将last的下个节点设为p(但此时不更新last,因为有可能这个p也是重复的,要再经过一轮判断才能确定) } else { last = p; // 说明p既不和它前面的值相等,也不和后面的值相等,所以可以确定p在新链表中 p = p.next; } } return first.next; } }
同样是设置头结点(自己写的,逻辑稍微清楚一些)
public ListNode deleteDuplication(ListNode pHead) { ListNode fake = new ListNode(0); ListNode temp = fake; while(pHead!=null){ if(pHead.next!=null&&pHead.next.val==pHead.val){ //前面的一个判断是必要的,防止后面求val出现空指针异常 int flag = pHead.val; while(pHead!=null&&pHead.val==flag) pHead = pHead.next; } else{ temp.next = pHead; temp = temp.next; pHead = pHead.next; } } temp.next = null; // 这一步必不可少,譬如12355的情况,判断完55后直接跳出了,3节点的next节点没有被设置 return fake.next; }
递归
public class Solution { public ListNode deleteDuplication_1(ListNode pHead) { // 递归停止条件 if (pHead == null || pHead.next == null) return pHead; ListNode current = pHead.next; // 如果pHead是重复元素 if (pHead.val == current.val) { current = current.next; while (current != null && current.val == pHead.val) current = current.next; pHead = current; return deleteDuplication_1(current); } else { // pHead不是重复元素 pHead.next = deleteDuplication_1(current); return pHead; } };
相关文章推荐
- 剑指offer——链表-删除链表中重复的结点
- 《剑指offer》刷题笔记(链表):删除链表中重复的结点
- (php实现剑指offer)删除链表中重复的结点
- 剑指offer-面试题57-删除链表中重复的结点
- (剑指Offer)面试题57:删除链表中的重复结点
- 剑指offer--删除链表中重复的结点
- 《剑指Offer》学习笔记--面试题57:删除链表中重复的结点
- 剑指offer 面试题57 删除链表中重复的结点
- 剑指offer(c++)——删除链表中重复的结点
- 剑指offer——删除链表中重复的结点
- 剑指offer(53)-删除链表中重复的结点
- 剑指offer--面试题57:删除链表中重复的结点
- 剑指offer-面试题57:删除链表中重复的结点
- 《剑指offer》-删除单链表中重复的结点
- 《剑指offer》:[57]删除链表中重复的结点
- 剑指offer 删除链表中重复的结点
- 《剑指offer》:删除链表中重复的结点
- 《剑指offer》面试题57 删除链表中重复的结点 C++ 实现 以及 错误总结 (指针问题)!!
- 剑指offer(四十三)之删除链表中重复的结点
- 剑指offer:删除链表中重复的结点