Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return
null
. - The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
如果两个链表有重复的部分,那么返回重复的起始位置,否则,返回null。
两种方法:
1、(参考discuss中,并非最佳答案)
可以利用hashMap,先把第一个链表的所有节点放入map中,然后再遍历第二个链表,看map中是否有相同的节点。如果没有,返回null。
时间复杂度O(m+n),空间复杂度O(m) or O(n)
2、先遍历一次链表,找出连个链表的最后一个节点(如果不一样,那么返回null)以及长度差(最佳)
然后较长的链表先走长度差个节点,
之后两个链表一起走,遇到相同的就返回。
时间复杂度O(m+n),空间复杂度O(1)
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { int len1 = 1,len2 = 1; if( headA == null || headB == null) return null; ListNode node1 = headA; ListNode node2 = headB; while( node1.next != null ){ node1 = node1.next; len1++; } while( node2.next != null ){ node2 = node2.next; len2++; } if( len1 == 0 || len2 == 0 || node1 != node2 ) return null; node1 = headA; node2 = headB; if( len1 > len2 ){ while( len1 > len2 ){ len1--; node1 = node1.next; } }else if( len1 < len2 ){ while( len1<len2){ len2--; node2 = node2.next; } } while( len1 >0 ){ if( node1 == node2 ) return node1; node1 = node1.next; node2 = node2.next; len1--; } return null; } }
3、(参考discuss)
不用第一次遍历找出长度差,一直循环遍历找出相同的节点(如果不存在会出现null)
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { //boundary check if(headA == null || headB == null) return null; ListNode a = headA; ListNode b = headB; //if a & b have different len, then we will stop the loop after second iteration while( a != b){ //for the end of first iteration, we just reset the pointer to the head of another linkedlist a = a == null? headB : a.next; b = b == null? headA : b.next; } return a; } }