OJ12:160. 相交链表

目录


题目

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

示例 1

输入 :intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出 :Intersected at '8'
解释 :相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。

从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。

在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

--- 请注意相交节点的值不为 1,因为在链表 A 和链表 B 之中值为 1 的节点 (A 中第二个节点和 B 中第三个节点) 是不同的节点。换句话说,它们在内存中指向两个不同的位置,而链表 A 和链表 B 中值为 8 的节点 (A 中第三个节点,B 中第四个节点) 在内存中指向相同的位置。
示例 2

输入 :intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出 :Intersected at '2'
解释 :相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。

从各自的表头开始算起,链表 A 为 [1,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
输出 :No intersection
解释 :从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。

由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。

这两个链表不相交,因此返回 null 。

思路分析

我们想要找到是否相交,就要找出指向相等的地址的节点·,这样就可以找到其相交的节点;

  1. 由于我们不知道两个链表的长度如何,所以我们要对较长的那个链表 "先走差距步"保证两个链表长度相等了之后,再移动。
    这样我们就要先算出两个链表的长度进行比较:
c 复制代码
//计算两个链表的长度
int la = 0;
int lb = 0;
ListNode* curA = headA;
ListNode* curB = headB;

while (curA)
{
	la++;
	curA->next;
}
while (curB)
{
	lb++;
	curB->next;
}
  1. 确定长链表,但是我们无法确定那个是长链表,所以我们假设A链表是长链表,如果不是,我们再作交换:
c 复制代码
//假设headA指向的链表长
ListNode* longNode = headA;
ListNode* shortNode = headB;
if (la < lb)  //假设不成立
{
	longNode = headB;
	shortNode = headA;
}
  1. 移动长链表的指针,使指针后的两个链表的节点个数一致
c 复制代码
int gap = abs(la - lb);
while (gap--)
{
	longNode = longNode->next;
}

4. 共同向后移动,直到找到指向相同的节点

c 复制代码
while (longNode)
{
	if (longNode == shortNode)
		return longNode;
	longNode = longNode->next;
	shortNode = shortNode->next;
}
return NULL;


代码展示

c 复制代码
struct ListNode {
    int val;
    struct ListNode* next;
};
typedef struct ListNode ListNode;
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
	if (headA == NULL || headB == NULL)
		return NULL;
	//计算两个链表的长度
	int la = 0;
	int lb = 0;
	ListNode* curA = headA;
	ListNode* curB = headB;

	while (curA)
	{
		la++;
		curA->next;
	}
	while (curB)
	{
		lb++;
		curB->next;
	}

	//假设headA指向的链表长
	ListNode* longNode = headA;
	ListNode* shortNode = headB;
	if (la < lb)  //假设不成立
	{
		longNode = headB;
		shortNode = headA;
	}

	int gap = abs(la - lb);
	while (gap--)
	{
		longNode = longNode->next;
	}

	while (longNode)
	{
		if (longNode == shortNode)
			return longNode;
		longNode = longNode->next;
		shortNode = shortNode->next;
	}
	return NULL;
}

相关推荐
饕餮怪程序猿5 分钟前
A*算法(C++实现)
开发语言·c++·算法
电饭叔9 分钟前
不含Luhn算法《python语言程序设计》2018版--第8章14题利用字符串输入作为一个信用卡号之二(识别卡号有效)
java·python·算法
2301_8002561139 分钟前
8.2 空间查询基本组件 核心知识点总结
数据库·人工智能·算法
不穿格子的程序员39 分钟前
从零开始写算法——矩阵类题:矩阵置零 + 螺旋矩阵
线性代数·算法·矩阵
ULTRA??1 小时前
C/C++函数指针
c语言·开发语言·c++
资深web全栈开发1 小时前
LeetCode 3432. 统计元素和差值为偶数的分区方案数
算法·leetcode
黎茗Dawn1 小时前
DDPM-KL 散度与 L2 损失
人工智能·算法·机器学习
wearegogog1231 小时前
DEA模型MATLAB实现(CCR、BCC、超效率)
开发语言·算法·matlab
业精于勤的牙1 小时前
浅谈:快递物流与算法的相关性(四)
算法
ghie90901 小时前
MATLAB自适应子空间辨识工具箱
数据结构·算法·matlab