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
思路:两个指针,先同时往下,等到第一个到末尾,第二个如果没到末尾,第一个将指针指向第二条头节点,反过来将第二个指针指向第一个头节点,如此,两指针指向到两链表末相等距离的指针
/**
* 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) {
ListNode p1 = headA,p2 = headB;
if(p1==null || p2==null) return null;
while(p1!=p2){
p1 = p1!=null?p1.next:headB;
p2 = p2!=null?p2.next:headA;
}
return p1;
}
}
这里有一点要注意:当两链表无交点时,两指针会最后同时指向null
思路二:用一个函数计算两链表长度,然后算出两起始指针
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA = length(headA), lenB = length(headB);
// move headA and headB to the same start point
while (lenA > lenB) {
headA = headA.next;
lenA--;
}
while (lenA < lenB) {
headB = headB.next;
lenB--;
}
// find the intersection until end
while (headA != headB) {
headA = headA.next;
headB = headB.next;
}
return headA;
}
private int length(ListNode node) {
int length = 0;
while (node != null) {
node = node.next;
length++;
}
return length;