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 求两个链表的交集的更多相关文章

  1. ✡ 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 ...

  2. 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 ...

  3. [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 ...

  4. [LintCode] Intersection of Two Linked Lists 求两个链表的交点

    Write a program to find the node at which the intersection of two singly linked lists begins. Notice ...

  5. [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 ...

  6. [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 ...

  7. [LeetCode]160. Intersection of Two Linked Lists判断交叉链表的交点

    方法要记住,和判断是不是交叉链表不一样 方法是将两条链表的路径合并,两个指针分别从a和b走不同路线会在交点处相遇 public ListNode getIntersectionNode(ListNod ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. 一道面试题关于js中逗号

    一.今天遇到一个面试题,自我感觉是会,但是却做错了.人都是这样,自我感觉良好,其实也就预警自己已经忽视一些细节以及一些自我感知. 面试题: ,j=,k; ,j<;i++,j++){ k=i+j; ...

  2. 解决SELinux导致Apache更改端口后无法启动的问题

    systemctl start httpd    # 将Apache的默认端口改为90后,启动Apache时提示失败 systemctl status httpd    # 查看Apache的状态 可 ...

  3. 使用树莓派GPIO控制继电器

      一.使用方法总结: VCC接+5v,GND接负,IN1接GPIO口, 二.然后使用Linux命令或者编程控制GPIO口高低电位即可,如:执行下列命令: gpio readall 列出所有针角 gp ...

  4. 大数据开发keras框架环境配置小结

    系统安装问题 win10+ubuntu16.04 在win10在需要security boot设置成disable,否则安装完后无法设置启动项. 安装完ubuntu重启,系统会直接进入win10,需要 ...

  5. 获取国定字符的内容split

    a="Time:20190822_111655_554 Start Cloud new case, Num=1, Input=/data/voice/20190725_035326_2_vo ...

  6. 使用selenium谷歌浏览器驱动配置:

    from selenium import webdriver#导入谷歌浏览器的chrome_driverchrome_driver = r"C:\python36\Lib\site-pack ...

  7. Impala内存优化(转载)

    一. 引言 Hadoop生态中的NoSQL数据分析三剑客Hive.HBase.Impala分别在海量批处理分析.大数据列式存储.实时交互式分析各有所长.尤其是Impala,自从加入Hadoop大家庭以 ...

  8. c++ 字符串相加

    1. append string a= "xxx"; string b="yyy"; a.append(b); 结果 a = “xxxyyy”;

  9. chef test-kitchen Could not load the 'vagrant' driver from the load path 问题解决

    今天使用chef 的kitchen,运行kitchen list 发现了如下错误: >>>>>> ------Exception------- >>&g ...

  10. Pollard-Rho算法求大数质因子

    /* * 大整数分解到现在都是世界级的难题,但却是一个重要的研究方向,大整数在公共密钥的研究上有着重要的作用 * Pollard Rho算法的原理就是通过某种方法得到两个整数a和b.而待分解的大整数为 ...