题目:
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
分析:
假设A走过的长度为a1+a2+c1+c2+c3,B走过的长度为b1+b2+b3+c1+c2+c3。当A先走到末尾,交换A=headB。而B则类似,走完后交换B=headA。
由上图可知,A和B一定会在c1相遇,因为A和B走了一样的长度,若最后相遇点为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) {
//给出两个链表,找出公共节点开始位置
if(headA==null||headB==null) return null;
ListNode preA=headA;
ListNode preB=headB;
while(preA!=preB){
preA=preA==null?headB:preA.next;
preB=preB==null?headA:preB.next;
}
return preA;
}
}
分析2:
/**
* 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 lenA=listLength(headA);
int lenB=listLength(headB);
//同步相同长度
ListNode curA=headA;
ListNode curB=headB;
if(lenA>lenB){
for(int i=lenA-lenB;i>0;i--){
curA=curA.next;
}
}else if(lenA<lenB){
for(int i=lenB-lenA;i>0;i--){
curB=curB.next;
}
}
//同步后比较
while(curA!=null&&curB!=null){
if(curA==curB){
return curA;
}else {
curA=curA.next;
curB=curB.next;
}
}
return curA;
}
public int listLength(ListNode head){
if(head==null)return 0;
ListNode pre=head;
int count=0;
while(pre!=null){
count++;
pre=pre.next;
}
return count;
}
}