0123 双指针 Day12
创始人
2024-04-22 02:45:19
0

剑指 Offer 25. 合并两个排序的链表

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {}
}

解题思路

由于初始状态合并链表中无节点,因此循环第一轮时无法将节点添加到合并链表中。

解决方案:初始化一个辅助节点 dum 作为合并链表的伪头节点,将各节点添加至 dum 之后。

算法流程:

1.初始化: 伪头节点 dum ,节点 cur 指向 dum 。

2.循环合并: 当 l1​ 或 l2​ 为空时跳出;

        当 l1.val < l2.val 时,cur 后继节点指定为 l1,并 l1 向前走一步

        当 l1.val >= l2.val 时,cur 后继节点指定为 l2,并 l2 向前走一步

        节点cur向前走一步,即 cur = cur.next

3.合并剩余尾部: 跳出时有两种情况,即 l1​ 为空 或 l2​ 为空。

        若 l1 != null,将 l1 添加至节点cur之后,否则将 l2 添加至cur之后

4.返回值: 合并链表在伪头节点 dum 之后,因此返回 tdum.next 即可

 

 

 

 

 

 

 

 

代码如下

class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {ListNode dum = new ListNode(0), cur = dum;while(l1 != null && l2 != null) {if(l1.val < l2.val) {cur.next = l1;l1 = l1.next;}else {cur.next = l2;l2 = l2.next;}cur = cur.next;}cur.next = l1 != null ? l1 : l2;return dum.next;}
}

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

输入两个链表,找出它们的第一个公共节点。

如下面的两个链表

在节点 c1 开始相交。

 

示例 1:

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

示例 2:

输入: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。

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/
class Solution {ListNode getIntersectionNode(ListNode headA, ListNode headB) {}
}

解题思路 

考虑构建两个节点指针 A​ , B 分别指向两链表头节点 headA , headB ,做如下操作:

指针 A 先遍历完链表 headA ,再开始遍历链表 headB ,当走到 node 时,共走步数为:
a + (b - c)

指针 B 先遍历完链表 headB ,再开始遍历链表 headA ,当走到 node 时,共走步数为:
b + (a - c)

如下式所示,此时指针 A , B 重合,并有两种情况:

a + (b - c) = b + (a - c)

若两链表 有 公共尾部 (即 c>0 ) :指针 A , B 同时指向第一个公共节点 node 。
若两链表 无 公共尾部 (即 c=0 ) :指针 A , B 同时指向 null 。

 

 

 

 

 

 

 

代码如下

public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {ListNode A = headA, B = headB;while (A != B) {A = A != null ? A.next : headB;B = B != null ? B.next : headA;}return A;}
}

 

 

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...