描述
给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。
例如:
给出的链表为1 \to 2\to 3\to 3\to 4\to 4\to51→2→3→3→4→4→5, 返回1\to 2\to51→2→5.
给出的链表为1\to1 \to 1\to 2 \to 31→1→1→2→3, 返回2\to 32→3.
数据范围:链表长度 0 \le n \le 100000≤n≤10000,链表中的值满足 |val| \le 1000∣val∣≤1000
要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)
进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)
public class DeleteDuplicatesListTwo {
static class ListNode {
int val;
ListNode next = null;
}
/*
* 我自己失败的思路,写不下去了
* 我也想到了使用三个指针,但我的思路主要放在了快指针。造成写不下去
*/
public ListNode deleteDuplicates (ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode preHead = new ListNode();
ListNode pre = preHead; // 满指针的前驱指针
preHead.next = head;
ListNode ps = preHead.next; // 慢指针
ListNode pf = ps.next; // 快指针
while(pf != null){
if(ps.val != pf.val){
ps = ps.next;
pf = pf.next;
pre = pre.next;
}else{
pf = pf.next;
}
pre.next = pf;
pf = pf.next;
}
return null;
}
public ListNode deleteDuplicates2 (ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode preHead = new ListNode();
preHead.next = head;
ListNode pre = preHead; // 当前指针的前驱指针
ListNode cur = head; // 当前指针
ListNode next = null; // 下一个指针
while(cur != null){
next = cur.next;
boolean tmp = false; // 是否有相同节点
while(next != null && cur.val == next.val){
next = next.next; // 移动到下一个节点
pre.next = next;
tmp = true; // 有相同节点
}
if(!tmp){
// 如果没有相同节点,调整 前驱指针pre。 如果有相同节点,则不调整
pre = cur;
}
cur = next;
}
return preHead.next;
}
public static void main(String[] args) {
}
}