算法通关村第一关——链表经典问题之两个链表的第一个公共节点笔记

52 阅读2分钟

白银挑战:链表的高频面试算法题

1.剑指 Offer 52. 两个链表的第一个公共节点

解法一:双指针差值; 遍历两个链表记录每个链表的长度;计算两个链表长度的差值;让长链表先走差值步;然后长,短链表一起走,直到碰到第一个相交位置;

image.png

class Solution {
    ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA = 0;
        int lenB = 0;
        ListNode curA = headA;
        ListNode curB = headB;
        while (curA != null) {
            lenA++;
            curA = curA.next;
        }
        while (curB != null) {
            lenB++;
            curB = curB.next;
        }
        curA = headA;
        curB = headB;
        int len = 0;
        if (lenA > lenB) {
            len = lenA - lenB;
            while (len > 0) {
                curA = curA.next;
                len--;
            }
        } else {
            len = lenB - lenA;
            while (len > 0) {
                curB = curB.next;
                len--;
            }
        }
        ListNode res=null;
        while (curA != null && curB != null) {
            if(curA==curB){
                res=curA;
                break;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return res;
    }
}

解法二:双指针; 假设两个链表的公共长度为 c ,链表1的总长度为 a, 链表2的总长度为 b;

指针left 先遍历完 headA链表,再开始遍历headB; 指针right 先遍历完B链表,再开始遍历headA,那么left 和 right 指针一定会在第一个公共节点相遇 (前提是 headA 和 headB 能相交);

为什么会相遇在第一个公共节点处?

left 先走完 headA,长度为 a ; 再遍历 headB,走到第一个公共节点处,长度为b-c; left总共走过的路程为 a+b-c;

right先走完headB,长度为b ; 再遍历 headA, 走到第一个公共节点处,长度为a-c;right总共走过的路程为b+a-c;

left 和 right 走过的路程相等;所以left,right 一定会在 第一个公共节点处相遇;

public static ListNode otherMethod(ListNode headA, ListNode headB) {
        ListNode left = headA;
        ListNode right = headB;
        ListNode res=null;
    // 循环结束的条件有两种,一种是left == null && right==null; 也就是left,right指针同时为null;这种情况只有在两个链表不相交的情况下才会出现
    // 另一种是找到了第一个公共的节点
        while (left !=null || right !=null) {
            if(left == right){
                res=left;
                break;
            }
            left = left != null ? left.next : headB;
            right = right != null ? right.next : headA;
        }
        return res;
}