首页 > 其他分享 >剑指Offer|LCR 023. 相交链表

剑指Offer|LCR 023. 相交链表

时间:2025-01-07 18:29:54浏览次数:8  
标签:LCR next 链表 let headB 023 node1 节点

LCR 023. 相交链表

给定两个单链表的头节点 headAheadB ,请找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null

图示两个链表在节点 c1 开始相交**:**

img

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构

示例 1:

img

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

img

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

img

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

提示:

  • listA 中节点数目为 m
  • listB 中节点数目为 n
  • 0 <= m, n <= 3 * 104
  • 1 <= Node.val <= 105
  • 0 <= skipA <= m
  • 0 <= skipB <= n
  • 如果 listAlistB 没有交点,intersectVal0
  • 如果 listAlistB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]

法1:

分析:

先计算两个链表的长度,将较长的链表先走到和短一点的连接一样的起始位置;

接着往后遍历,如果结点相等,则说明找到了,不等接着遍历。

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( 1 ) O(1) O(1)

// 定义 ListNode 类(假设已经定义过该类)
class ListNode {
    constructor(val = 0, next = null) {
        this.val = val;
        this.next = next;
    }
}

function countList(head) {
    // 计算链表长度
    let count = 0;
    while (head !== null) {
        count++;
        head = head.next;
    }
    return count;
}

function getIntersectionNode(headA, headB) {
    const count1 = countList(headA);
    const count2 = countList(headB);
    const delta= Math.abs(count1 - count2);
    
    let longer = count1 > count2 ? headA : headB; // 长一点的链表
    let shorter = count1 > count2 ? headB : headA; // 短一点的链表
    
    let node1 = longer;
    // 让 长一点的链表 先走到 和 短一点的链表 一样的起始位置
    for (let i = 0; i < delta; ++i) {
        node1 = node1.next;
    }

    let node2 = shorter;
    // 当两个结点相等的话,就说明找到了
    // 不等就接着向后遍历
    while (node1 !== node2) {
        node2 = node2.next;
        node1 = node1.next;
    }
    return node1;
}

let node1 = new ListNode(1);
let node2 = new ListNode(2);
let node3 = new ListNode(3);
let node4 = new ListNode(4);
let node5 = new ListNode(5);
let node6 = new ListNode(6);

// 链表 A: 1 -> 2 -> 3 -> 4
node1.next = node2;
node2.next = node3;
node3.next = node4;

// 链表 B: 6 -> 5 -> 4
node6.next = node5;
node5.next = node4;

// 获取交点节点
let intersectionNode = getIntersectionNode(node1, node6);
console.log(intersectionNode); // 输出交点节点(node4)

法2:

分析:

利用两个链表headAheadB相加总的结点数是相同的。

首先遍历指针a是否与指针b相等,遇到空节点,则a赋值为headB,b赋值为headA,比较巧妙。

在这里插入图片描述

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( 1 ) O(1) O(1)

var getIntersectionNode = function (headA, headB) {
    let a = headA, b = headB;
    while(a != b) {
        a = a !== null ? a.next : headB;
        b = b !== null ? b.next : headA;
    }
    return a;
};

标签:LCR,next,链表,let,headB,023,node1,节点
From: https://blog.csdn.net/Catherinemin/article/details/144965225

相关文章

  • 2023 ICPC 亚洲区域赛济南站 K.Gifts from Knowledge
    前言模拟赛做到的,破防了思路知道是一个大概什么做法,我在考试思路的基础上继续想一下?首先对于每一列,我们可以求出哪些集合不共存,经过\(\mathcal{O}(nm)\)的预处理之后问题转化为给定\(m\)个集合,要求选择的方案数使得选出的点集中,不存在两个点在同一集合内......
  • [PKUSC 2023 D1T3] 天气预测
    一棵以\(1\)为根的树,每个点\(u\)有一对权值\((a_u,b_u)\),\(a_u\)为\(1\)的概率为\(p_u\),为\(0\)的概率为\(1-p_u\)。确定\(a_u\)后,计算\(b_u\)为\(a_u\)与\(b_v\)(\(v\)为\(u\)的子节点)的众数(保证子节点个数为偶数个,即参与计算众数的点数为奇数)。求\(b_1\)......
  • (即插即用模块-Attention部分) 三十六、(2023) DCA 二重交叉注意力
    文章目录1、DualCross-Attention2、代码实现paper:DualCross-AttentionforMedicalImageSegmentationCode:https://github.com/gorkemcanates/Dual-Cross-Attention1、DualCross-AttentionU-Net及其变体尽管在医学图像分割任务中取得了良好的性能,但仍然存......
  • 德普微一级代理 DP023N10TGN TOLL DPMOS N-MOSFET 100V 300A 1.75mΩ
    Features•UsesadvancedTrenchMOSFET-DPMOStechnology•Extremelylowon-resistanceRDS(on)•ExcellentQgxRDS(on)product(FOM)•QualifiedaccordingtoJEDECcriteriaProductSummaryPart#:DP023N10TGNVDS:100VRDS(on).typ:1.75m......
  • C++学习笔记#01——指针与链表
    在自学C++的时候,发现指针是一个很难绕开的东西,看了一些参考资料和别人的程序,写一些垃圾。Part1指针指针是一个指向一片内存地址的变量,相当于家的门牌号。我们即可以通过变量名来访问一个变量,也可以通过它对应的地址来访问。就像你的老师可以点你的名字找你,也可以找你宿舍的门......
  • 142环形链表
    最简单的思路:哈希。进阶那个快慢指针确实想不到。//哈希,空间为O(n)classSolution{public:ListNode*detectCycle(ListNode*head){unordered_set<ListNode*>adds;if(head==nullptr)returnNULL;ListNode*cur=head;......
  • 合并两个排序的链表(C++)
    问题描述输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排序的。数据范围:0≤n≤10000≤n≤1000,−1000≤节点值≤1000−1000≤节点值≤1000要求:空间复杂度O(1)O(1),时间复杂度O(n)O(n)如输入{1,3,5},{2,4,6}时,合并后的链表为{1,2,3,4,5,......
  • python中的链表
    在Python中,链表不是内置的数据结构,但可以通过类的方式实现自定义链表。以下是链表在刷算法题中常用的语法和操作方法。1.定义链表节点链表节点是一个包含值和指向下一个节点的指针的结构:classListNode:def__init__(self,val=0,next=None):self.val=val......
  • 138. 随机链表的复制(中)
    目录题目哈希表题目深拷贝一个链表,要求新链表中的每个节点都是新创建的,并且这些节点的random指针都指向新链表中的相应节点。哈希表先使用Map建立映射,然后根据映射将random和next指针指向对应的节点或者nullvarcopyRandomList=function(head){//如果链表为空......
  • ruoyi若依前端验证码不显示的终极解决方法.20230721
    ​搞了3天啊,查了各种资料啊。然后使劲的看log啊,总算搞定了啊。一般情况,本地开发环境测试没问题,部署到服务器就各种不适应,就是服务器配置的问题了。本次这种验证码不显示,典型的nginx的配置问题。正确的nginx配置如下:events{worker_connections1024;}http{i......