题目:编写一个程序,找到两个单链表相交的起始节点
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解题思路:
如果A 和 B 两个链表相交于 c1:
重要关系:则一定存在这样的关系:a + c + b + c = b + c + a + c;
发现这样的规律后:
- 将A链表的头结点headA赋给ListNode l1, B链表的头结点headB赋给ListNode l2;
- 让l1遍历A链表,当l1到达A链表的尾结点Null时,此时l1走过长度为(a+c),此时将B链表的头结点headB赋给l1, 让l1去遍历B链表,l1再去走(b+c)的长度;
同理,让l2遍历B链表,当l2到达B链表的尾结点Null时,此时l2走过长度为(b+c),此时将A链表的头结点headA赋给l2, 让l2去遍历A链表,l1再去走(a+c)的长度; - 当l1走过(a+c+b)时,l2走过(b+c+a)时,因为两个链表相交于c1,所以会有l1==l2。退出循环。
如果A,B链表不相交,则a + b = b + c,l1和l2会同时到达Null.l1==l2, 退出循环。
代码:
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode l1 = headA, l2 = headB;
while (l1 != l2) {
l1 = (l1 == null) ? headB : l1.next;
l2 = (l2 == null) ? headA : l2.next;
}
return l1;
}
特殊情况
特殊情况1:A,B中有空节点。
特殊情况2:A,B两个链表在起始相交,则一开始l1==l2,退出循环。
时间空间复杂度
时间复杂度:O(m+n)
空间复杂度:O(1)
刚开始想错的地方
当出现这种情况时,以为是1,但不对,因为1只是两个链表的节点值相等,并不是equals, 堆内存地址相等。
拓展:
如果只判断两个链表是否有交点:
- 直接比较两个链表的尾结点是否相同(有一种特殊情况,两个链表在头结点相交,这样是一个开叉状,不是收敛状,所以是比较两个链表的头结点或者尾结点是否相同)
参考:https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3%20-%20%E9%93%BE%E8%A1%A8.md