zoukankan      html  css  js  c++  java
  • LeetCode142.环形链表II(链表中环的入口节点)

    题目

    给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

    说明:不允许修改给定的链表。

    进阶:

    你是否可以使用 O(1) 空间解决此题?

    输入:head = [3,2,0,-4], pos = 1
    输出:返回索引为 1 的链表节点
    解释:链表中有一个环,其尾部连接到第二个节点。
    
    
    输入:head = [1], pos = -1
    输出:返回 null
    解释:链表中没有环。
    

    提示:
    链表中节点的数目范围在范围 [0, 104] 内

    -105 <= Node.val <= 105

    pos 的值为 -1 或者链表中的一个有效索引

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/linked-list-cycle-ii
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题思路

    哈希表

    循环链表,每次循环将节点指针存储到哈希表
    每次循环时判断当前节点是否已经存在。
    
    时间复杂度:O(n)空间复杂度:O(n)
    

    快慢指针

    https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/
    
    假设环外节点个数为a,环内节点个数为b
    慢指针每次走一步,快指针每次走两步,
    假设慢指针走过的步数为s,快指针走过的步数为f
    当两指针相遇时:f = 2s 因为快指针速度是慢指针两倍
    又可以推导出:f = s + nb 因为快指针进入环以后一直在里面打圈圈,刚好要多走n圈
    所有可以推导出:s = nb
    从头节点开始走到入环节点需要走:a + nb,
    当快慢指针相遇时,慢指针已经走了nb,只需要再走a就可以到达环入口,
    然后我们让快指针指向头节点走a路程,
    即两指针会在环入口处相遇。
    
    时间复杂度:O(n)空间复杂度:O(1)
    

    代码

    type ListNode struct {
    	Val int
    	Next *ListNode
    }
    
    // 哈希表法
    func detectCycle(head *ListNode) *ListNode {
    	m := map[*ListNode]struct{}{}
    	for head != nil{
    		if _,ok := m[head];ok{
    			return head
    		}
    		m[head] = struct{}{}
    		head = head.Next
    	}
    	return nil
    }
    
    // 快慢指针
    func detectCycle2(head *ListNode) *ListNode {
    	// 定义快慢指针
    	slow,fast := head,head
    	for fast != nil{
    		// 慢指针每次走一步
    		slow = slow.Next
    		// 如果快指针没有下一个节点了,说明没有环
    		if fast.Next == nil{
    			return nil
    		}
    		// 快指针每次走两步
    		fast = fast.Next.Next
    		// 如果快慢指针相遇则代表有环
    		if fast == slow {
    			// 从头开始遍历,在环入口处与慢指针相遇
    			p := head
    			for p != slow {
    				p = p.Next
    				slow = slow.Next
    			}
    			return p
    		}
    	}
    	return nil
    }
  • 相关阅读:
    LintCode Python 简单级题目 488.快乐数
    LintCode Python 简单级题目 100.删除排序数组中的重复数字 101.删除排序数组中的重复数字II
    LintCode Python 简单级题目 373.奇偶分割数组
    LintCode Python 简单级题目 39.恢复旋转排序数组
    LintCode Python 简单级题目 35.翻转链表
    LintCode Python 简单级题目 451.两两交换链表中的节点
    LintCode Python 简单级题目 174.删除链表中倒数第n个节点
    aws查看官方centos镜像imageid
    linux shell脚本查找重复行/查找非重复行/去除重复行/重复行统计
    php配置优化-生产环境应用版
  • 原文地址:https://www.cnblogs.com/hzpeng/p/15228914.html
Copyright © 2011-2022 走看看