单链表的交集
2016-12-26 00:00
281 查看
原题
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.
题目大意
找两个单链表的交集部分。如果没有交集返回null。
函数操作后,单链表必须返回他们原来的结构。
假定整个链表中没有环。
函数必须在O(N)时间复杂度,O(1)空间复杂度以内完成。
解题思路
先将其中一个链表的链头按到另一个链表的尾部,如果他们有交集则会构成一个环,题目等价于找链表中的环的起始结点。找到后将链表还原。代码实现
结点类public class ListNode { int val; ListNode next; ListNode(int x) { val = x; next = null; } }
算法实现类
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) { return null; } ListNode ta; // 用于记录headA链表的尾结点 ListNode ha = headA; // 第一步、找到headA的尾结点 while (ha.next != null) { ha = ha.next; } ta = ha; // 记录链表headA的尾结点 // 第二步、将headB接到ta后面 ta.next = headB; // 第三步、判断是否存在环 // 判断链表是否存在环,办法为: // 设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步, // 如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。 // (当然,fast先行头到尾部为NULL,则为无环链表)程序如下: ListNode fast = headA; // 每次前进一步 ListNode slow = headA; // 每次前进二步 while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { // 如果相遇了就退出来 break; } } // 没有环的情况 if (fast == null || fast.next == null) { ta.next = null; // 解开拼接好的链表 return null; } // 有环的情况 // 找到环的入口点 // 当fast若与slow相遇时,slow肯定没有走遍历完链表,而fast已经在环内循环了n圈(1<=n)。 // 假设slow走了s步,则fast走了2s步(fast步数还等于s 加上在环上多转的n圈),设环长为r,则: // // 2s = s + nr // s= nr // // 设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。 // a + x = nr // a + x = (n – 1)r +r = (n-1)r + L - a // a = (n-1)r + (L – a – x) // // (L – a – x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点, // 于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。 slow = headA; while (slow != fast) { fast = fast.next; slow = slow.next; } ta.next = null; return slow; } }
相关文章推荐
- 比较版本号
- Excell列标题
- 主元素
- Excel表行号
- 微信JS-SDK之图像接口开发详解
- redis分布式锁方案
- innoDB索引使用和优化汇总
- brew install mysql
- jdbc 获取结果集行数、获取生成id、批量插入
- 大型商场导购App定制开发|明智科技
- mac下安装ffmpeg
- 总记不住的
- httpclient pool使用工具类
- MapUtils
- spring mvc自定义异常打印处理
- srping mvc 中controller dao service entity包及类自动建造
- css中float和position属性
- django与celery实现异步队列任务
- windows 7 服务命令开机启动
- MySQL字符串与数字互转