[LeetCode] 160. Intersection of Two Linked Lists 求两个链表的交集
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return
null. - The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
Credits:
Special thanks to @stellari for adding this problem and creating all test cases.
求两个链表的交点,要求Time: O(n), Space: O(1)
解法1:交点最早可能出现在短链表的第一个节点,后面的节点两个链表一样。所以,长链表的比短链表开始多出的那些就没用。求出两个链表的长度差值,把较长的链表向后移动这个差值,变成一样长。然后在一个一个的比较。
解法2: 双指针,用两个指针pA和pB分别指向链表A和B。然后让它们分别遍历整个链表,每步一个节点。当pA到达链表末尾时,让它指向B的头节点(没错,是B);类似的当pB到达链表末尾时,重新指向A的头节点。如果pA在某一点与pB相遇,则pA/pB就是交集开始的节点。
Java: Solution 1
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
int lenA = getLength(headA), lenB = getLength(headB);
if (lenA > lenB) {
for (int i = 0; i < lenA - lenB; ++i) headA = headA.next;
} else {
for (int i = 0; i < lenB - lenA; ++i) headB = headB.next;
}
while (headA != null && headB != null && headA != headB) {
headA = headA.next;
headB = headB.next;
}
return (headA != null && headB != null) ? headA : null;
}
public int getLength(ListNode head) {
int cnt = 0;
while (head != null) {
++cnt;
head = head.next;
}
return cnt;
}
}
Java: Solution 2
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) return null;
ListNode a = headA, b = headB;
while (a != b) {
a = (a != null) ? a.next : headB;
b = (b != null) ? b.next : headA;
}
return a;
}
}
Python:
class Solution:
# @param two ListNodes
# @return the intersected ListNode
def getIntersectionNode(self, headA, headB):
if headA is None or headB is None:
return None pa = headA # 2 pointers
pb = headB while pa is not pb:
# if either pointer hits the end, switch head and continue the second traversal,
# if not hit the end, just move on to next
pa = headB if pa is None else pa.next
pb = headA if pb is None else pb.next return pa # only 2 ways to get out of the loop, they meet or the both hit the end=None # the idea is if you switch head, the possible difference between length would be countered.
# On the second traversal, they either hit or miss.
# if they meet, pa or pb would be the node we are looking for,
# if they didn't meet, they will hit the end at the same iteration, pa == pb == None, return either one of them is the same,None
Python: wo
class Solution(object):
def getIntersectionNode(self, headA, headB):
if not headA or not headB:
return None a, b = headA, headB
while a != b:
a = a.next if a else headB
b = b.next if b else headA return a
Python: Solution 1
class Solution(object):
def getIntersectionNode(self, headA, headB):
lenA = self.getListLen(headA)
lenB = self.getListLen(headB)
if lenA > lenB:
for i in range(lenA - lenB):
headA = headA.next
elif lenA < lenB:
for i in range(lenB - lenA):
headB = headB.next
while headA != headB:
headA, headB = headA.next, headB.next
return headA def getListLen(self, head):
length = 0
while head:
length += 1
head = head.next
return length
Python: Solution 2
class ListNode:
def __init__(self, x):
self.val = x
self.next = None class Solution:
# @param two ListNodes
# @return the intersected ListNode
def getIntersectionNode(self, headA, headB):
curA, curB = headA, headB
begin, tailA, tailB = None, None, None # a->c->b->c
# b->c->a->c
while curA and curB:
if curA == curB:
begin = curA
break if curA.next:
curA = curA.next
elif tailA is None:
tailA = curA
curA = headB
else:
break if curB.next:
curB = curB.next
elif tailB is None:
tailB = curB
curB = headA
else:
break return begin
C++:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB) return NULL;
int lenA = getLength(headA), lenB = getLength(headB);
if (lenA < lenB) {
for (int i = 0; i < lenB - lenA; ++i) headB = headB->next;
} else {
for (int i = 0; i < lenA - lenB; ++i) headA = headA->next;
}
while (headA && headB && headA != headB) {
headA = headA->next;
headB = headB->next;
}
return (headA && headB) ? headA : NULL;
}
int getLength(ListNode* head) {
int cnt = 0;
while (head) {
++cnt;
head = head->next;
}
return cnt;
}
};
C++:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (!headA || !headB) return NULL;
ListNode *a = headA, *b = headB;
while (a != b) {
a = a ? a->next : headB;
b = b ? b->next : headA;
}
return a;
}
};
类似题目:
[LeetCode] 349. Intersection of Two Arrays 两个数组相交
[LeetCode] 350. Intersection of Two Arrays II 两个数组相交II
All LeetCode Questions List 题目汇总
[LeetCode] 160. Intersection of Two Linked Lists 求两个链表的交集的更多相关文章
- ✡ leetcode 160. Intersection of Two Linked Lists 求两个链表的起始重复位置 --------- java
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- LeetCode 160. Intersection of Two Linked Lists (两个链表的交点)
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- [LeetCode] Intersection of Two Linked Lists 求两个链表的交点
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- [LintCode] Intersection of Two Linked Lists 求两个链表的交点
Write a program to find the node at which the intersection of two singly linked lists begins. Notice ...
- [LeetCode] 160. Intersection of Two Linked Lists 解题思路
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- [LeetCode]160.Intersection of Two Linked Lists(2个链表的公共节点)
Intersection of Two Linked Lists Write a program to find the node at which the intersection of two s ...
- [LeetCode]160. Intersection of Two Linked Lists判断交叉链表的交点
方法要记住,和判断是不是交叉链表不一样 方法是将两条链表的路径合并,两个指针分别从a和b走不同路线会在交点处相遇 public ListNode getIntersectionNode(ListNod ...
- Leetcode 160. Intersection of two linked lists
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- Java for LeetCode 160 Intersection of Two Linked Lists
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
随机推荐
- python代码安全扫描工具
python代码安全扫描工具:Coverity. Fortify.SecMissile(漏扫,对源代码提供基于语义的搜索和分析能力,实现已知安全漏洞的快速扫描)
- 【云栖社区001-数据结构】如何实现一个高效的单向链表逆序输出(Java版)
如题 动手之前,发现自己很擅长用C语言来写链表. 不过,既然自己做的是Java开发,那么还是用Java实现这个算法吧:毕竟,以后的若干年里都差不多要跟Java打交道了. 于是,先将Java版的链表自学 ...
- C# 验证控件的使用RequiredFieldValidator&CompareValidator
使用验证控件可以向服务器提交表单数据时验证表单内容,下面以RequiredFieldValidator和CompareValidator为例说明验证控件的用法 RequiredFieldValidat ...
- 记录一下使用element ui使用级联选择器的坑,级联选择器的默认选中
Cascader 级联选择器 使用级联选择器我使用的是默认选中值 下面是我的数据格式,只是形式相同,值不同, 后台的数据是这样的不是ID //级联选择器 <el-cascader :props= ...
- MySql常用函数大全
MySql常用函数大全 MySQL数据库中提供了很丰富的函数.MySQL函数包括数学函数.字符串函数.日期和时间函数.条件判断函数.系统信息函数.加密函数.格式化函数等.通过这些函数,可以简化用户的操 ...
- EF 多数据库切换配置(MSSQL/MySql)
<?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访 ...
- web自动化测试-自动化测试模型介绍
一.线性测试 什么是线性测试? 通过录制或编写对应用程序的操作步骤产生相应的线性脚本,每个测试脚本相对独立,不产生依赖和调用,单纯的来模拟用户完整的操作场景 缺点 1.开发成本高,测试用例之间存在重复 ...
- 4、NameNode启动过程详解
NameNode 内存 本地磁盘 fsimage edits 第一次启动HDFS 格式化HDFS,目的就是生成fsimage start NameNode,读取fsimage文件 start Data ...
- Chirp信号及其生成
Chirp信号是一个典型的非平稳信号,在通信.声纳.雷达等领域具有广泛的应用. 简介 Chirp译名:啁啾(读音:“周纠”),是通信技术有关编码脉冲技术中的一种术语,是指对脉冲进行编码时,其载频在脉冲 ...
- C++ EH Exception(0xe06d7363)----抛出过程
C++ EH Exception是Windows系统VC++里对c++语言的throw的分类和定义,它的代码就是0xe06d7363.在VC++里其本质也是SEH结构化异常机制.在我们分析用户崩溃的例 ...