题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
栈解法
遍历链表,将不重复的节点压栈,栈底则为不重复链表的表头,每次遍历的节点与栈顶的节点比较,若相同则将栈顶节点出栈,循环找到下一个不和当前节点重复的节点
,并将新的栈顶节点的下一个节点指向这个不和当前节点重复的节点
。
import java.util.Stack;
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
Stack<ListNode> stack = new Stack<>();
ListNode new_head = null;
while (pHead != null) {
if (!stack.isEmpty()) {
ListNode top = stack.peek();
if (top.val == pHead.val) {
stack.pop(); // 去掉栈顶的重复元素
// 找到下一个不重复的元素
while (pHead != null && pHead.val == top.val)
pHead = pHead.next;
if (!stack.isEmpty()) {
ListNode next = stack.peek(); // 获取新的栈顶元素
next.next = pHead; // 并将其下个节点指向这个不重复的节点
}
} else {
stack.push(pHead); // 不是一个重复元素
pHead = pHead.next;
}
} else {
// 栈为空
stack.push(pHead);
new_head = pHead; // 栈底元素作为新的表头
pHead = pHead.next;
}
}
if (stack.isEmpty())
return null;
return new_head;
}
}
递归法
递归法三要素,递归出口、递归过程、递归初始条件。递归的思想是:若当前节点是重复节点,则循环找到下一个不重复的节点,若当前节点不是重复节点,则为它寻找下一个不重复的节点
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if (pHead == null || pHead.next == null)
return pHead;
if (pHead.val == pHead.next.val) {
// 重复节点
ListNode tmp = pHead;
while (tmp != null && tmp.val == pHead.val)
tmp = tmp.next;
// 找到第一个不和当前节点重复的节点,并从它开始继续递归
return deleteDuplication(tmp);
} else {
// 当前节点不是重复节点,则将它指向下一个不重复的节点
pHead.next = deleteDuplication(pHead.next);
return pHead;
}
}
}
指针法
可以使用两个指针pre
和last
,last
指针负责寻找下一个不重复的节点,pre
指针负责删除重复的节点(即将next
指向下一个不重复的节点),为了方便,我们在链表头多加一个节点,并让pre
指向它,last
指向pre
的下一个节点,同时需要用一个res
指针保留头节点的值。
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
ListNode pre, last, res;
pre = new ListNode(-1);
res = pre;
pre.next = pHead;
last = pHead;
while (last != null && last.next != null) {
if (last.val == last.next.val) {
// 这是一个重复节点
ListNode tmp = last;
while (tmp != null && tmp.val == last.val)
tmp = tmp.next;
// tmp是第一个不重复的节点
pre.next = tmp;
last = tmp;
} else {
// 如果不重复,则两个指针齐头并进
pre = last;
last = last.next;
}
}
return res.next;
}
}