链表的题目总结

一  单链表中的双指针

快慢指针找环的问题

如果存在环,快指针总能追上慢指针。

什么速度合适?其他速度怎么样?

例子:

 Linked List Cycle

Given a linked list, determine if it has a cycle in it.

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if head is None or head.next is None:
            return False
        
        slow = head
        fast = head.next
        # 比较安全的速度是fast是slow的两倍,也就是说每次fast比slow多跑一格。
        # 如果fast过快,而且环很小的话,fast每次恰好跨过一个环,和slow永远无法相遇
        # 如果fast过快,需要判断的条件过长 fast.next fast.next.next fast.next.next...
        while fast.next and fast.next.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False

 Linked List Cycle II

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

比较简单的做法,用hash表记录访问过的位置。空间是O(n)的。快慢指针的方法空间是O(1)。

快慢指针相遇的点是不确定的,但是快指针比慢指针多走过的距离是确定,恰好等于慢指针到环入口的位置。

用三个阶段,很容易解释:

设起点到环入口点的距离为x, 环的的长度为c,

一, 当slow指针到达入口点的时候,t = x次,  fast移动的距离为 2 * x,相当于fast不仅到达了环而且已经在环中走了x的距离,此时fast距离slow的距离为 c - x

二 在环中的追击问题,fast 距离 slow 为 c - x,又因为fast的相对速度为1, 所以 移动 t = c - x次后, slow和fast相遇。当slow和fast相遇,此时slow 走过了 t * 1 = c - x 的距离, 那么相遇点距离 入口的距离就是 c - (c - x) =  x

三 得到了距离关系,从起点到入口点距离为x, 从相遇点到入口点的距离也是x,所以两个点同时同速移动就一定会在入口点

相遇。

class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        cur = head
        visited = set()

        while cur:
            if cur in visited:
                return cur
            else:
                visited.add(cur)
                cur = cur.next
        return None
        
        
            
#         if head is None or head.next is None:
#             return None
        
#         slow = head
#         fast = head
        
#         hascycle = False
        
#         while fast.next and fast.next.next:
#             fast = fast.next.next
#     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值