给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
总结:
- 了解了java中的几种像hashSet,Stack等结构
- 开始自己想的是集合法,并且类型指定为Integer即可,不占内存嘛,
但是发现如果有相同的数但又不存在环怎么办,所以最后只能使用节点来判断 - 第一种方法很巧妙其实就有点像高中物理的追击问题,但是最开始
p2.next != null
一直没有想明白,最后画图发现了代码中的解释,所以一定要多动笔多画,把自己当做是解决问题的机器,解决问题 - 观阴阳之开阖以名命物,知存亡之门户,筹策万类之始终,达人心之理,变化之朕焉,而守司其门户。故圣人之在天下也,自古及今,其道一也。变化无穷,各有所归,或陰或陽,或柔或刚,或开或闭,或驰或张。
参考代码
public boolean hasCycle(ListNode head) {
/**第一种方法快慢指针*/
/*总体思想:其实就是每次快慢(p1,p2)指针的差距增加1,只要有环两者一定会相遇
* 相当于物理当中的追击问题 或者说是 两个人围绕操场跑步*/
// if (head == null) {
// return false;
// }
// ListNode p1 = head;
// ListNode p2 = head.next;
// /*为什么p2.next != null,因为p2 = p2.next.next需要成立就得有这个,
// *如果p2.next != null, 可能会有
// * 1. p2.next后面没有元素,则此时p2 = p2.next.next为null,是符合规范的
// * 2.p2.next后面有元素,则此时p2 = p2.next.next为某个元素这个很好理解*/
// while ((p1 != null) && (p2 != null) &&(p2.next != null)) {
// p1 = p1.next;
// p2 = p2.next.next;
// if (p1 == p2) {
// return true;
// }
// }
// return false;
/**第二种方法:集合法(思路好理解)
* 思路总结:把结点放入到一个hastSet中如果存在 则一定存在环 因为都有相同的结点了很好理解
* 但是由于每一次放入节点都需要比较,所以自然速度很慢
* 并且还开辟了一定的空间*/
if (head == null) {
return false;
}
HashSet<ListNode> hashSet = new HashSet<>();
while (head != null) {
/*如果当前节点已经包含,返回false;否则放入集合*/
if (hashSet.contains(head)) {
return true;
}
hashSet.add(head);
head = head.next;
}
return false;
}
2021年9月19日
题目来源力扣链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/xnwzei/