https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/
题目描述
输入两个链表,找出它们的第一个公共节点。
输入输出样例
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
裁剪法
两个链表的长度是不一样的,如何到达他们两个共同的交点呢?
需要让在两个指针在链表上面走的时候,两个指针是同步运动的。
将长的那个链表剪短即可。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
// 先得到两个链表的长度
int len = 0;
ListNode ha = headA;
ListNode hb = headB;
while(ha != null){
len++;
ha = ha.next;
}
while(hb != null){
len--;
hb = hb.next;
}
// 如果len小于0,说明headB链表长一些
if(len < 0){
ha = headB;
hb = headA;
}else{
ha = headA;
hb = headB;
}
// 让长的链表先走len步,相当于将两个链表的起点变为一致了
for(int i=0; i<Math.abs(len); i++){
ha = ha.next;
}
// 两个同时走
while(ha != null){
if(ha == hb) return ha;
ha = ha.next;
hb = hb.next;
}
return null;
}
}
数学分析法
分析一下两个链表:
- 假设headA链表,非公共部分长度为 a
- 假设headB链表,非公共部分长度为 b
- headA链表和headB链表的公共部分,长度为 c
headA = a + c
headB = b + c
headA + headB = (a+c) + (b+c)
headB + headA = (b+c) + (a+c)
两个链表同时走,如果一个链表走到头,立马去走另一条链表。这样两者走过的距离是一样的,变相地将两个链表的距离拉成相等的了。
代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode ha = headA, hb = headB;
// 出while循环只有一种情况,ha=hb。
// ha=hb有两种情况,一种两个都是null,一种两个都有值
while(ha != hb){
if(ha != null) ha = ha.next;
else ha = headB;
if(hb != null) hb = hb.next;
else hb = headA;
}
return ha;
}
}