您的位置:首页 > Web前端

剑指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}

你的输出为:

{}

没有考虑最后一个节点的特殊情况。

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;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: