两个链表的第一个公共结点

题目描述:输入两个链表,找出它们的第一个公共结点。

思路:如果两个链表有公共结点,则第一个公共结点以及之后的所有结点都是重合的,即至少它们的尾结点是重合的。因为两个链表长度不一定相等,所以同步遍历时不能保证两个链表同时到达尾结点。假设一个链表比另一个多k个结点,先在长的链表上遍历k个结点即尾部对齐,再同步遍历,保证同时到达尾结点,即同时到达第一个公共结点。也就是说,同步遍历时第一个相同结点就是第一个公共结点。

步骤:

1 如果两个链表至少有一个是空,则返回null。

2 分别获取两个链表的长度len1和len2。

3 通过比较两个链表的长度来获取长度差k,并使长链表遍历k个结点。

4 通过同步遍历来查找第一个公共结点,如果查找到公共结点,则返回该结点。

5 返回null。

时间复杂度:O(len1+len2)。

Java代码:

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode list1, ListNode list2) {
        // 如果两个链表至少有一个是空,则返回null
        if (list1 == null || list2 == null) {
            return null;
        }
        
        // 分别获取两个链表的长度len1和len2
        int len1 = getListLength(list1);
        int len2 = getListLength(list2);
        
        // 通过比较两个链表的长度来获取长度差k,并使长链表遍历k个结点
        if (len1 > len2) {
            list1 = walkSteps(list1, len1 - len2);
        } else {
            list2 = walkSteps(list2, len2 - len1);
        }
        
        // 通过同步遍历来查找第一个公共结点,如果查找到公共结点,则返回该结点
        while (list1 != null) {
            if (list1 == list2) {
                return list1;
            }
            
            list1 = list1.next;
            list2 = list2.next;
        }
        
        // 返回null
        return null;
    }
    
    // 获取链表长度
    private int getListLength(ListNode list) {
        int len = 1;
        while (list.next != null) {
            list = list.next;
            len++;
        }
        
        return len;
    }
    
    // 获取当前结点走了k步之后的结点
    private ListNode walkSteps(ListNode list, int k) {
        while (k-- > 0) {
            list = list.next;
        }
        
        return list;
    }
}

 

posted on 2025-11-29 15:09  王景迁  阅读(0)  评论(0)    收藏  举报

导航