zoukankan      html  css  js  c++  java
  • 142. Linked List Cycle II

    1. 原始题目

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

    To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

    Note: Do not modify the linked list.

    Example 1:

    Input: head = [3,2,0,-4], pos = 1
    Output: tail connects to node index 1
    Explanation: There is a cycle in the linked list, where tail connects to the second node.
    

    Example 2:

    Input: head = [1,2], pos = 0
    Output: tail connects to node index 0
    Explanation: There is a cycle in the linked list, where tail connects to the first node.
    

    Example 3:

    Input: head = [1], pos = -1
    Output: no cycle
    Explanation: There is no cycle in the linked list.
    

    2. 题目理解

    这道题是 141. Linked List Cycle的升级版。就是不仅要确认是否有环。若有环的话,还要输出环的入口结点。

    所以第一步是141题的做法,先确认有无环。然后要确认环中元素的个数m。然后快慢指针从头开始走,快指针先走m步,然后快慢指针同步一步一步地走,当再次相遇时,两者就在环的入口处啦。

    3. 解题

     1 class Solution(object):
     2     def detectCycle(self, head):
     3         """
     4         :type head: ListNode
     5         :rtype: ListNode
     6         """
     7         
     8         if not head or not head.next:
     9             return None
    10         cur = head
    11         pre = head
    12         exist_cycle = False   # default no cycle
    13         while pre:
    14             pre = pre.next
    15             cur = cur.next
    16             if pre:
    17                 pre = pre.next
    18             if pre==cur:
    19                 exist_cycle = True
    20                 break                     # 以上步骤确认是否有环
    21             
    22         if exist_cycle:
    23             num = 1
    24             while(pre.next!=cur):
    25                 pre = pre.next
    26                 num+=1                    # num返回环中元素的个数  
    27                 
    28             pre = head
    29             cur = head
    30            
    31             for _ in range(num):          # 快指针先走num步
    32                 pre = pre.next
    33             while(pre!=cur):           
    34                 pre = pre.next
    35                 cur = cur.next
    36             return pre                    # 两者相遇即相等时就是环的入口啦 
    37         

    这是常规解法。Leetcode上一个小哥根据公式计算出一种更间接的操作:尤其是最后的一个循环

     1 class Solution:
     2     # @param head, a ListNode
     3     # @return a list node
     4     def detectCycle(self, head):
     5         try:
     6             fast = head.next
     7             slow = head
     8             while fast is not slow:
     9                 fast = fast.next.next
    10                 slow = slow.next
    11         except:
    12             # if there is an exception, we reach the end and there is no cycle
    13             return None
    14 
    15         # since fast starts at head.next, we need to move slow one step forward
    16         slow = slow.next
    17         while head is not slow:
    18             head = head.next
    19             slow = slow.next
    20 
    21         return head

    4. 验证

     1 # 新建链表1
     2 listnode1 = ListNode_handle(None)
     3 s1 = [3,2,666,0,-4]
     4 for i in s1:
     5     listnode1.add(i)
     6 listnode1.cur_node.next = listnode1.head.next.next       # 构建循环链表,即将尾指针再指向头后面后面的元素,即6666
     7 
     8 
     9 s = Solution()
    10 head = s.detectCycle(listnode1.head)                     # python3.5
    11 print(head)
    12 print(head.val)

    <__main__.ListNode object at 0x00000247132B9940>
    666

  • 相关阅读:
    第五章 Mybatis注解
    第四章 Mbatis高级查询
    第三章 Mybatis动态Sql
    第二章 Mybatis映射文件
    第一章 初识Mybatis
    Mybatis大纲设计
    项目总结
    第二周项目功能实现
    第一周项目功能实现
    客车网上售票系统需求分析
  • 原文地址:https://www.cnblogs.com/king-lps/p/10661283.html
Copyright © 2011-2022 走看看