142. 环形链表 II

思路:

设链表共有 a+b 个节点,其中 链表头部到链表入口 有 a 个节点(不计链表入口节点), 链表环 有 b 个节点。

再设两指针分别走了 f,s 步,则有:

  • f = 2sf=2s;
  • fast 比 slow多走了 n 个环的长度,即 f = s + nbf=s+nb;
  • 以上两式相减得:f = 2nbf=2nb,s = nbs=nb;

概括一下:

根据:

  1. f=2s (快指针每次2步,路程刚好2倍)
  2. f = s + nb (相遇时,刚好多走了n圈)

推出:s = nb

从head结点走到入环点需要走 : a + nb, 而slow已经走了nb,那么slow再走a步就是入环点了。

如何知道slow刚好走了a步? 从head开始,和slow指针一起走,相遇时刚好就是a步。

Java实现

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
while(true) {
if(fast == null || fast.next == null) return null;
fast = fast.next.next;
slow = slow.next;
if(fast == slow) break;
}
fast = head;
while (fast != slow){
fast = fast.next;
slow = slow.next;
}
return fast;
}
}

Python实现

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution(object):
def detectCycle(self, head):
fast, slow = head, head
while True:
if not (fast and fast.next): return
fast, slow = fast.next.next, slow.next
if fast == slow: break
fast = head
while fast != slow:
fast, slow = fast.next, slow.next
return fast

141. 环形链表

142少去算法部分。单纯用快慢指针判断是否相遇即刻。

Java实现

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode fast = head, slow = head;
while(true) {
if(fast == null || fast.next == null) return false;
fast = fast.next.next;
slow = slow.next;
if(fast == slow) return true;
}
}
}

Python实现

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
fast, slow = head, head
while True:
if not (fast and fast.next): return False
fast = fast.next.next
slow = slow.next
if fast == slow: return True

最新文章

  1. 【已更新】【原创】Chrome53 最新版惊现无厘头卡死 BUG!
  2. app xml报错
  3. 自动封装Servlet HttpServletRequest请求成为一个POJO对象
  4. Greenplum的全量恢复之gpdbrestore
  5. Why Every Professional Should Consider Blogging
  6. C# 框架是什么?MVC是什么 ?工厂模式是什么?设计模式是什么?三层架构是什
  7. A Case for Flash Memory SSD in Enterprise Database Applications
  8. 第四篇:Eclipse Android app 工程迁移到 Android Studio
  9. 数据库对于null值的处理
  10. shell变量赋值进阶
  11. Robot Framework开发系统关键字详细
  12. python3 中encode 和decode的使用方法。
  13. SQLI DUMB SERIES-22
  14. 为什么开启子进程 一定要放在 if __name__ == '__main__' 下面
  15. JDK命令行工具
  16. Codeforces 977F - Consecutive Subsequence - [map优化DP]
  17. 运维工具Ansible安装部署
  18. react-native-vector-icons 图标库使用
  19. curl库的使用,32-64
  20. linux下查看线程数的几种方法

热门文章

  1. 图解|用好MySQL索引,你需要知道的一些事情
  2. Linux环境下安装配置JDK1.8
  3. 【基础】工作中常用的linux命令,经常会被面试官问到
  4. kafka 第一次小整理(草稿篇)————分发的基本思路[三]
  5. Java设计模式之单例模式理解
  6. P5018 [NOIP2018 普及组] 对称二叉树
  7. C++设计模式 - 命令模式(Command)
  8. APIO2015 八邻旁之桥/巴邻旁之桥
  9. 什么是BGP
  10. 超硬核解析!Apache Hudi灵活的Payload机制