LeetCode Intersection of Two Linked Lists

本文介绍了一种在两个单链表中找到它们开始相交节点的算法。通过分析链表长度差异并调整遍历起点,确保了两链表在相交处同步相遇,实现了O(n)的时间复杂度和O(1)的空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.
思路分析:这题考察链表操作,首先要正确理解题意。如果两个链表有intersection,那么最后一个node必然是同一个node,否则就是没有intersection。然后如果我们已经知道两个链表有intersection,如果去找第一个交叉的node呢?最直接的方法是用两个指针同时在两个链表走,但是如何保证它们可以同时到达那个首个交叉的node呢?我们可以让这两个指针的起点不同,保证他们同时走的时候,到达首个交叉的node的距离相等。于是我们想到利用两个链表的长度之差|len1 - len2|.如果len1 > len2,那么就先让pa先走|len1 - len2|步,然后pa和pb一起走,必然同时到达首个交叉的node。对于len1 <= len2的情况,同理可以分析。
AC Code
/**
 * 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 pa = headA;
        ListNode pb = headB;
        int lenA = 1;
        int lenB = 1;
        while(pa.next != null){
            pa = pa.next;
            lenA++;
        }
        while(pb.next != null){
            pb = pb.next;
            lenB++;
        }
        if(pa != pb) return null; //no intersection
        pa = headA;
        pb = headB;
        int diff = Math.abs(lenA - lenB);
        if(lenA > lenB){
            while(diff != 0 ){
                pa = pa.next;
                diff--;
            }
        } else {
            while(diff != 0){
                pb = pb.next;
                diff--;
            }
        }
        while(pa != pb){
            pa = pa.next;
            pb = pb.next;
        }
        return pa;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值