快慢指针-----Linked List Cycle II
2016-01-25 12:59
351 查看
题目描述:
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Follow up:
Can you solve it without using extra space?
题目大意:
给定一个链表,返回循环的起始节点。如果没有环,则返回空。
进一步思考:
你可以在不使用额外空间的条件下完成题目吗?
解题思路:
Linked List Cycle II
1). 使用快慢指针法,若链表中有环,可以得到两指针的交点M
2). 记链表的头节点为H,环的起点为E
2.1) L1为H到E的距离
2.2) L2为从E出发,首次到达M时的路程
2.3) C为环的周长
2.4) n为快慢指针首次相遇时,快指针在环中绕行的次数
根据L1,L2和C的定义,我们可以得到:
慢指针行进的距离为L1 + L2
快指针行进的距离为L1 + L2 + n * C
由于快慢指针行进的距离有2倍关系,因此:
2 * (L1+L2) = L1 + L2 + n * C => L1 + L2 = n * C => L1 = (n - 1)* C + (C - L2)
可以推出H到E的距离 = 从M出发绕环到达E时的路程
因此,当快慢指针在环中相遇时,我们再令一个慢指针从头节点出发
接下来当两个慢指针相遇时,即为E所在的位置
Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Follow up:
Can you solve it without using extra space?
题目大意:
给定一个链表,返回循环的起始节点。如果没有环,则返回空。
进一步思考:
你可以在不使用额外空间的条件下完成题目吗?
解题思路:
Linked List Cycle II
1). 使用快慢指针法,若链表中有环,可以得到两指针的交点M
2). 记链表的头节点为H,环的起点为E
2.1) L1为H到E的距离
2.2) L2为从E出发,首次到达M时的路程
2.3) C为环的周长
2.4) n为快慢指针首次相遇时,快指针在环中绕行的次数
根据L1,L2和C的定义,我们可以得到:
慢指针行进的距离为L1 + L2
快指针行进的距离为L1 + L2 + n * C
由于快慢指针行进的距离有2倍关系,因此:
2 * (L1+L2) = L1 + L2 + n * C => L1 + L2 = n * C => L1 = (n - 1)* C + (C - L2)
可以推出H到E的距离 = 从M出发绕环到达E时的路程
因此,当快慢指针在环中相遇时,我们再令一个慢指针从头节点出发
接下来当两个慢指针相遇时,即为E所在的位置
/** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { * this.val = val; * this.next = null; * } * } */ public class Solution { /** * @param head: The first node of linked list. * @return: The node where the cycle begins. * if there is no cycle, return null */ public ListNode detectCycle(ListNode head) { // write your code here if (head == null || head.next==null) { return null; } ListNode fast, slow; fast = head.next; slow = head;//快慢指针初始化 fast为1 slow为0; while (fast != slow) { if(fast==null || fast.next==null) return null; fast = fast.next.next; slow = slow.next; } //是否有环 while (head != slow.next) { head = head.next; slow = slow.next; }//找到开始节点....... return head; } }
相关文章推荐
- Android基于XMPP Smack openfire 开发的聊天室(四) 【创建房间、表单;报文】
- linx性能监控
- Android基于XMPP Smack openfire 开发的聊天室(三) 【新旧记录、踢人】
- Gradle Android 引入os文件的3种方式
- Head First C (前半部分)读书笔记
- c#之转义字符
- qt发布 2
- Android基于XMPP Smack openfire 开发的聊天室(二) 【聊天信息、成员】
- Unix时间戳和北京时间相互转换
- Leetcode Bit Manipulation 题型总结
- Win8.1蓝屏错误代码0×c0000034怎么办
- eclipse快捷键
- 操作引入xml文件的书包(定位到指定节点)
- 使用WPScan扫描wordpress获取用户密码
- 解决Xcode7安装KSImageNamed插件不好使问题
- 基于XMPP协议的Android即时通信系
- [Linphone Android] 应答请求
- MFC - 查看操作进程
- Android基于XMPP Smack openfire 开发的聊天室(一)
- RHCE 学习笔记(8) 服务管理