文章目录
——————————————————————————————————————
141. 环形链表(简单)
哈希表
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null) return false;
Map<ListNode, Integer> map = new HashMap<>();
ListNode p = head;
while(p != null){
if(map.containsKey(p)){
return true;
}else{
map.put(p, 1);
}
p = p.next;
}
return false;
}
}
集合
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null) return false;
Set<ListNode> set = new HashSet<>();
ListNode p = head;
while(p != null){
if(set.add(p) == false){
return true;
}
//官解优化:这一段可以去掉,因为上面已经添加过了
/*else{
set.add(p);
}*/
p = p.next;
}
return false;
}
}
快慢指针(「Floyd 判圈算法」(又称龟兔赛跑算法))
1.假设有个哑结点,两者同时从哑结点出发
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null) return false;
ListNode slow = head;
ListNode fast = head.next;
while(slow != fast){
if(fast == null || fast.next == null) return false;
slow = slow.next;
fast = fast.next.next;
}
return true;
}
}
2.没有哑结点,两者同时从头结点出发
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null) return false;
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast) return true;
}
return false;
}
}
142. 环形链表 II(中等)
快慢指针
只能用没有哑结点的形式,因为用了哑结点,链表中就多出来一个节点
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {
//检测有没有环,使用快慢指针slow(一次走一步)和fast(一次走两步)
//if(head == null || head.next == null) return null;
//这个地方不写也行
ListNode slow = head;
ListNode fast = head;
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
if(slow == fast) break;
}
if(fast == null || fast.next == null) return null;
//System.out.println("找到了" + slow.val);
//找位置,当找到环之后,slow从head出发,fast从相遇点出发,一次都走一步,再次相遇为环的入口点
slow = head;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}