目录
题1:删除排序链表中的重复元素 II
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。
返回同样按升序排列的结果链表。
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii
解法:思路写在注释里
class Solution {
public ListNode deleteDuplicates(ListNode head) {
// 0、1个节点
if(head==null || head.next==null) return head;
ListNode dummy = new ListNode(-101, head); // 创建一个dummy节点,指向头节点
ListNode pre = dummy, post = head;
while(post!=null && post.next!=null){
if(post.val == post.next.val){
int common = post.val; // 记录下重复的值
while(post!=null && post.val==common){ // 碰到重复的值就跳过
post = post.next;
} // 退出这层while后,可能又恰好碰到一个重复的,交由外层while判断
}else{
pre.next = post;
pre = post;
post = post.next;
}
}
pre.next = post;
return dummy.next;
}
}
题2:两个链表的第一个公共节点
输入两个链表,找出它们的第一个公共节点。注意,不存在环。
https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/
空间复杂度O(n) 解法:通过map来存储其中一个链表的节点,再去遍历另一个链表
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
Map<ListNode,Object> map = new HashMap<ListNode, Object>();
Object obj = new Object();
while(headA!=null){
map.put(headA, obj);
headA=headA.next;
}
while(headB!=null){
if(map.get(headB)!=null) return headB;
headB = headB.next;
}
return null;
}
空间复杂度O(1)解法:
链表L1和链表L2的公共长度为C,非公共长度分别为A和B,二者总长是A+B+C。同时遍历L1和L2,L1遍历到尾部时,定位到L2的头节点,此时L1已经走了A+C步,再在L2上走B步。L2遍历到尾部的时候,定位到L1的头节点,L2走了B+C步,再在L1上走A步。
// 时间复杂度O(1)
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a=headA, b=headB;
// 长度相同且不相交时,则都走到了最后一个节点的next节点,也就是null
// 长度不同时,必然会相交
while(a!=b){
a = a==null? headB:a.next;
b = b==null? headA:b.next;
}
return a;
}