LCR 023. 相交链表

2024-04-21 00:12
文章标签 链表 相交 lcr 023

本文主要是介绍LCR 023. 相交链表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

图示两个链表在节点 c1 开始相交:
在这里插入图片描述
题目数据 保证 整个链式结构中不存在环。

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

示例 1:
在这里插入图片描述
输入: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:
在这里插入图片描述

输入: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:
在这里插入图片描述
输入: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
  • 如果 listA 和 listB 没有交点,intersectVal 为 0
  • 如果 listA 和 listB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]

思路:
1、将一个链表中的每个节点指针值(地址)插入哈希表
2、遍历另一个链表,如果存在节点指针值(地址)相同,即为同一个节点

ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {unordered_set<ListNode* > visited;ListNode *tem = headA;while (tem != nullptr) {visited.insert(tem);tem = tem->next;}tem = headB;while (tem != nullptr) {if (visited.count(tem)) {return tem;}tem = tem->next;}return nullptr;
}

注意:如果想要在idea中测试,使用这种方式解算的话,测试用例需要千万不可写为:

std::vector<int> numsn1 = { 4,1,8,4,5 };
std::vector<int> numsn2 = { 5,6,1,8,4,5 };
ListNode *l01 = createLinkedList(numsn1);
ListNode *l02 = createLinkedList(numsn2);
getIntersectionNode(l01, l02);

交叉链表结构本质上指的是链表中两个节点所指向的地址相同,而非链表节点中的val相同。上边这样写指的是两个单独的链表,并未交叉(地址不同)。

因此,该结构应该像下边这样写:

std::vector<int> numsn1 = { 4 };
std::vector<int> numsn2 = { 5,6};
std::vector<int> numsn3 = { 1, 8, 4, 5 };
ListNode *l01 = createLinkedList(numsn1);
ListNode *l02 = createLinkedList(numsn2);
ListNode *l03 = createLinkedList(numsn3);

之后再将l03分别插入在l01 和l02 之后,这样才满足交叉链表的结构。因为交叉链表,并不是链表节点的值相等,而是链表指针所指向的地址相同。

这篇关于LCR 023. 相交链表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/921697

相关文章

LeetCode--234 回文链表

题目 请判断一个链表是否为回文链表。 示例 示例 1:输入: 1->2输出: false示例 2:输入: 1->2->2->1输出: true /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val

LeetCode--206 反转链表

题目 反转一个单链表。 示例 示例:输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL class Solution {public:ListNode* reverseList(ListNode* head) {if (head == nullptr || head->next == nullptr){return head;}ListNo

剑指offer(C++)--两个链表的第一个公共结点

题目 输入两个链表,找出它们的第一个公共结点。 解法一 两个链表一定有交点的话,方法是指向短链表指针先走完,然后指向长链表,指向长链表指针后走完,指向短链表。所以,第二次走过,一定会在交点相遇。 class Solution {public:ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {ListN

算法6— 判断两个链表是否相交

问题: 给出两个单向链表的头指针,比如h1、h2,判断链表是否相交,如果不相交返回NULL;如果相交,返回指向第一个相交节点的指针。时间复杂度控制在O(n)。 分析: 如果两单向链表相交的话,一定是Y型相交,不可能出现X型,弄清楚这点后接下来的工作就是: (1)先找到h1,h2的最后一个节点L1和L2,同时记录节点数量a,b;(这里假设 a > b) (2)判断最后一个节点是否相同

剑指Offer—编程题56(链表中环的入口地址)

题目:一个链表中包含环,如何找出环的入口结点? 解题思路   可以用两个指针来解决这个问题。先定义两个指针P1和P2指向链表的头结点。如果链表中环有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。    剩下的问题就是如何得到环中结点的数目。我们在面试题15的第二个相关题目时用到

剑指Offer—编程题15(链表中倒数第k个结点)

题目:输入一个链表,输出该链表中倒数第k 个结点.为了符合大多数人的习惯,本题从1 开始计数,即链表的尾结点是倒数第1 个结点.例如一个链表有6 个结点,从头结点开始它们的值依次是1 、2、3、4、5 、6。这个个链表的倒数第3 个结点是值为4 的结点. public static class ListNode {int value;ListNode next;} 解题思路:

Java数据结构4-链表

1. ArrayList的缺陷 由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。因此:java集合中又引入了LinkedList,即链表结构。 2. 链表 2.1 链表的概念及结构 链表是一种物理存储结构上非连续存储结构,数据元素

LeetCode.25K个一组翻转链表详解

问题描述 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。 k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。 问题理解 给定一个链表和一个数字 k,任务是将链表中的每 k 个节点做一次翻转,如果链表的长度不是 k 的整数倍,则剩余

leetcode刷题(40)——83. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3->3 输出: 1->2->3 平时我们删除一个链表中的某个元素,一般都是以下的写法: temp.next = temp.next.next; 这样temp.next就被删除了 此题解法如下: class Solution

leetcode刷题(39)——反转链表 II

这道题可以说是非常难的,2中解法,迭代和递归,递归更加难想出来 解法1:迭代链接反转 算法 在看具体算法之前,有必要先弄清楚链接反转的原理以及需要哪些指针。举例而言,有一个三个不同结点组成的链表 A → B → C,需要反转结点中的链接成为 A ← B ← C。 假设我们有两个指针,一个指向结点 A,一个指向结点 B。 分别记为 prev 和 cur。则可以用这两个指针简单地实现 A 和 B