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

For example, the following two linked lists:

  1. A: a1 a2

  2. c1 c2 c3

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

我还以为以后在不能免费做OJ的题了呢,想不到 OJ 又放出了不需要买书就能做的题,业界良心啊,哈哈^_^。这道求两个链表的交点题要求执行时间为 O(n),则不能利用类似冒泡法原理去暴力查找相同点,事实证明如果链表很长的话,那样的方法效率很低。我也想到会不会是像之前删除重复元素的题一样需要用两个指针来遍历,可是想了好久也没想出来怎么弄。无奈上网搜大神们的解法,发觉其实解法很简单,因为如果两个链长度相同的话,那么对应的一个个比下去就能找到,所以只需要把长链表变短即可。具体算法为:分别遍历两个链表,得到分别对应的长度。然后求长度的差值,把较长的那个链表向后移动这个差值的个数,然后一一比较即可。代码如下:

C++ 解法一:

  1. class Solution {
  2. public:
  3. ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
  4. if (!headA || !headB) return NULL;
  5. int lenA = getLength(headA), lenB = getLength(headB);
  6. if (lenA < lenB) {
  7. for (int i = ; i < lenB - lenA; ++i) headB = headB->next;
  8. } else {
  9. for (int i = ; i < lenA - lenB; ++i) headA = headA->next;
  10. }
  11. while (headA && headB && headA != headB) {
  12. headA = headA->next;
  13. headB = headB->next;
  14. }
  15. return (headA && headB) ? headA : NULL;
  16. }
  17. int getLength(ListNode* head) {
  18. int cnt = ;
  19. while (head) {
  20. ++cnt;
  21. head = head->next;
  22. }
  23. return cnt;
  24. }
  25. };

Java 解法一:

  1. public class Solution {
  2. public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  3. if (headA == null || headB == null) return null;
  4. int lenA = getLength(headA), lenB = getLength(headB);
  5. if (lenA > lenB) {
  6. for (int i = 0; i < lenA - lenB; ++i) headA = headA.next;
  7. } else {
  8. for (int i = 0; i < lenB - lenA; ++i) headB = headB.next;
  9. }
  10. while (headA != null && headB != null && headA != headB) {
  11. headA = headA.next;
  12. headB = headB.next;
  13. }
  14. return (headA != null && headB != null) ? headA : null;
  15. }
  16. public int getLength(ListNode head) {
  17. int cnt = 0;
  18. while (head != null) {
  19. ++cnt;
  20. head = head.next;
  21. }
  22. return cnt;
  23. }
  24. }

这道题还有一种特别巧妙的方法,虽然题目中强调了链表中不存在环,但是我们可以用环的思想来做,我们让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况,一种情况是在交点处相遇,另一种情况是在各自的末尾的空节点处相等。为什么一定会相等呢,因为两个指针走过的路程相同,是两个链表的长度之和,所以一定会相等。这个思路真的很巧妙,而且更重要的是代码写起来特别的简洁,参见代码如下:

C++ 解法二:

  1. class Solution {
  2. public:
  3. ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
  4. if (!headA || !headB) return NULL;
  5. ListNode *a = headA, *b = headB;
  6. while (a != b) {
  7. a = a ? a->next : headB;
  8. b = b ? b->next : headA;
  9. }
  10. return a;
  11. }
  12. };

Java 解法二:

  1. public class Solution {
  2. public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
  3. if (headA == null || headB == null) return null;
  4. ListNode a = headA, b = headB;
  5. while (a != b) {
  6. a = (a != null) ? a.next : headB;
  7. b = (b != null) ? b.next : headA;
  8. }
  9. return a;
  10. }
  11. }

类似题目:

Minimum Index Sum of Two Lists

参考资料:

https://leetcode.com/problems/intersection-of-two-linked-lists/

https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49792/Concise-JAVA-solution-O(1)-memory-O(n)-time

https://leetcode.com/problems/intersection-of-two-linked-lists/discuss/49785/Java-solution-without-knowing-the-difference-in-len!

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Intersection of Two Linked Lists 求两个链表的交点的更多相关文章

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

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

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

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

  5. LeetCode OJ: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. Intersection of Two Linked Lists (求两个单链表的相交结点)

    题目描述: Write a program to find the node at which the intersection of two singly linked lists begins. ...

  7. Intersection of Two Linked Lists(两个链表的第一个公共节点)

    来源:https://leetcode.com/problems/intersection-of-two-linked-lists Write a program to find the node a ...

  8. LeetCode: Intersection of Two Linked Lists 解题报告

    Intersection of Two Linked Lists Write a program to find the node at which the intersection of two s ...

  9. LeetCode——Intersection of Two Linked Lists

    Description: Write a program to find the node at which the intersection of two singly linked lists b ...

随机推荐

  1. NSSortDescriptor 的使用

    NSSortDescriptor  是什么 ? 你可以将它看做是对一个排序规则的描述者  因为我们可以使用它来对我们数组中的对象进行排序操作 假设现在有这样一个需求: 数组里面有十个Person对象 ...

  2. Entity Framework Extended Library

    扩展了实体框架的功能类库. https://github.com/loresoft/EntityFramework.Extended 1批量更新/删除 1)删除 //delete all users ...

  3. Pyc 是什么东东

    在众多语言中, 最终我们可以将语言分为编译性语言和解释性语言两种 编译性语言,也就是机器语言, 是机器能读的懂的语言, 像C语言, 其实高级语言都是基于C语言的基础之上运行的 解释性语言, 不同于编译 ...

  4. Python 基础之三条件判断与循环

    If……else 基本结构: If condition: do something else: do something 或者 If condition: do something elif cond ...

  5. Eclipse代码和xml文件的智能提示

    一.代码智能提示 Windows → Preferences → Java→ Editor → Content Assist 将 Auto activation delay(ms): 改为 0 将 A ...

  6. 工作中常用的git命令

    一 常用Git命令 git clone:(区分SSH or HTTP) git init:初始化仓库 二 Git命令详解 Git Bash下,cd /c git clone,从远程Git版本库克隆一份 ...

  7. html中role的作用

    role 是增强语义性,当现有的HTML标签不能充分表达语义性的时候,就可以借助role来说明. 通常这种情况出现在一些自定义的组件上,这样可增强组件的可访问性.可用性和可交互性. role的作用是描 ...

  8. 如何采用easyui tree编写简单角色权限代码

    首先每个管理员得对应一个角色: 而角色可以操作多个栏目,这种情况下我们可以采用tree多选的方式: 在页面上js代码: $('#Permission').dialog({ title: '栏目权限', ...

  9. unable to boot the simulator,无法启动模拟器已解决

    突然模拟器报错:unable to boot the simulator(无法启动模拟器) 试了好几种解决办法,删除所有的模拟器重启以后再添加,删除钥匙串登陆中的证书,重新安装Xcode都不行 最后通 ...

  10. [swift]NSURLSession

    一.简单说明 在iOS9.0之后,以前使用的NSURLConnection过期,苹果推荐使用NSURLSession来替换NSURLConnection完成网路请求相关操作. NSURLSession ...