链表中环的问题

1.如何确定链表中是否有环

LeetCode 142题:环形链表 II

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

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

在这里插入图片描述

  • 1.1 Hash表
    想要去判断有环,最简单的就是通过Hash,先遍历所有节点并存入hashmap中,如果存在环,那么出现相同节点时,这个节点就是环的入口
public ListNode detectCycle(ListNode head) {
    ListNode cur = head;
    Set<ListNode> map = new HashSet<ListNode>();

    while(cur != null){
        if(map.contains(cur)){
             return cur;
        }else{
            map.add(cur);
        }
        cur = cur.next;
    }
    return null;
}
  • 1.2 快慢指针
    定义两个指针slow与fast,slow每次走1步fast每次走2步,如果存在环,那么最后fast一定会与slow相遇。
    在这里插入图片描述

    • 假如fast离slow之间有一个空格,如上图情况一所示,fast与slow下一步就共同到了3,就会相遇了。
    • 假如fast离slow之间有两个空格,如上图情况二所示,fast下一步到3,slow下一步到4,就如情况一一样了。
public boolean hasCycle(ListNode head){
	if (head == null || head.next == null) return false;
	ListNode fast = head;
	ListNode slow = head;
	while(fast != null & fast.next != null){
		fast = fast.next.next;
		slow = slow.next;
		if (fast==slow)
			return true;
	}
	return false;
}

2.如何确定链表中环的入口

同样可以使用hash表来解决,就是第一个出现相同节点时,这个节点即为环的入口。
当使用双指针来解决时,需要先通过快慢指针的方式找到slow与fast相遇的节点,再令p1从最开始出发,p2从相遇节点出发,两个指针以相同速度前进那么p1p2相遇的时候就为环的入口,具体原因看骨头哥的解析。

public ListNode detectCycle(ListNode head){
	if(head == null){
		return null;
	}
	ListNode slow = head,fast = head;
	while(fast != null && fast.next != null){
		slow = slow.next;
		if(fast.next != null){
			fast = fast.next.next;
		}else{
			return null
		}
		if(slow == fast){
			ListNode ptr = head;
			while(ptr == slow){
				slow = slow.next;
				ptr = ptr.next;
			}
			return ptr;
		}
	}
	return null;
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值