[LeetCode] 160. 相交链表

1. 问题描述

160. 相交链表 - 力扣(LeetCode)


2. 实现思路

2.1 自己的思路

~~(一定要写出来啊喂)~

完全没思路…想过反转链表,这样开头就是共同的节点了,但是感觉好像不用这样写

2.2 题解思路

双指针技巧:链表相交问题(力扣 160 链表相交)

好吧果然是想复杂了,首先将链表尾对齐,然后逐个看就行了

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA = headA;
        ListNode* curB = headB;
        int lenA = 0, lenB = 0;
        while (curA != NULL) { // 求链表A的长度
            lenA++;
            curA = curA->next;
        }
        while (curB != NULL) { // 求链表B的长度
            lenB++;
            curB = curB->next;
        }
        curA = headA;
        curB = headB;
        // 让curA为最长链表的头,lenA为其长度
        if (lenB > lenA) {
            swap (lenA, lenB);
            swap (curA, curB);
        }
        // 求长度差
        int gap = lenA - lenB;
        // 让curA和curB在同一起点上(末尾位置对齐)
        while (gap--) {
            curA = curA->next;
        }
        // 遍历curA 和 curB,遇到相同则直接返回
        while (curA != NULL) {
            if (curA == curB) {
                return curA;
            }
            curA = curA->next;
            curB = curB->next;
        }
        return NULL;
    }
};
public ListNode GetIntersectionNode(ListNode headA, ListNode headB)
{
    if (headA == null || headB == null) return null;
    ListNode cur1 = headA, cur2 = headB;
    while (cur1 != cur2)
    {
        cur1 = cur1 == null ? headB : cur1.next;
        cur2 = cur2 == null ? headA : cur2.next;
    }
    return cur1;
}
  • 时间复杂度:O(n + m)
  • 空间复杂度:O(1)

2.3 优化(或者敲一遍题解?)

  • 好,首先是根据对齐的思路来敲的一遍
/*
 * @lc app=leetcode.cn id=160 lang=csharp
 *
 * [160] 相交链表
 */

var s = new Solution();
s.GetIntersectionNode();

public class ListNode
{
    public int val;
    public ListNode next;
    public ListNode(int x) { val = x; }
}

// @lc code=start
public class Solution
{
    public ListNode GetIntersectionNode(ListNode headA, ListNode headB)
    {
        int lenA = 1;
        int lenB = 1;
        var curA = headA;
        var curB = headB;
        while (curA.next != null)
        {
            curA = curA.next;
            lenA++;
        }
        while (curB.next != null)
        {
            curB = curB.next;
            lenB++;
        }

        // 保证A最长
        curA = headA;
        curB = headB;
        if (lenB > lenA)
        {
            (lenA, lenB) = (lenB, lenA);
            (curA, curB) = (curB, curA);
        }

        // 对齐
        int gap = lenA - lenB;
        while (gap-- > 0)
            curA = curA.next;

        while (curA != curB)
        {
            curA = curA.next;
            curB = curB.next;
            if (curA == null || curB == null) return null;
        }
        return curA;        
    }
}
// @lc code=end

  • 然后是leetcode上一个比较简单的哈希实现方法
/*
 * @lc app=leetcode.cn id=160 lang=csharp
 *
 * [160] 相交链表
 */

var s = new Solution();
s.GetIntersectionNode();

public class ListNode
{
    public int val;
    public ListNode next;
    public ListNode(int x) { val = x; }
}

// @lc code=start
public class Solution
{
    public ListNode GetIntersectionNode(ListNode headA, ListNode headB)
    {
        // 将A节点存入哈希表
        ISet<ListNode> visited = new HashSet<ListNode>();
        var temp = headA;
        do
        {
            visited.Add(temp);
            temp = temp.next;
        } while (temp != null);

        // 遍历B查询交叉节点
        temp = headB;
        do
        {
            if (visited.Contains(temp)) return temp;
            temp = temp.next;
        } while (temp != null);
        return null;
    }
}
// @lc code=end

  • 最佳是双指针法:

160. 相交链表 - 力扣(LeetCode)

public class Solution
{
    public ListNode GetIntersectionNode(ListNode headA, ListNode headB)
    {
        if (headA == null || headB == null) return null;
        var a = headA;
        var b = headB;

        while (a != b)
        {
            a = a == null ? headB : a.next;
            b = b == null ? headA : b.next;
        }

        return a;
    }
}

3. 补充知识と杂谈,总结

posted @ 2026-08-10 13:03  绘星tsuki  阅读(7)  评论(0)    收藏  举报