引言
由 “LSGO软件技术团队” 组织的 “基础算法刻意练习” 采用分类别练习的模式,即选择了五个知识点(数组、链表、字符串、树、贪心算法),每个知识点选择了 三个简单、两个中等、一个困难 等级的题目,共计三十道题,利用三十天的时间完成这组刻意练习。以下是我的每日打卡记录:
Task09.环形链表
-
Leecode第141题
-
难度:简单
-
题目概述:
给定一个链表,判断链表中是否有环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置 (索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 示例 1: 输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。 示例 2: 输入:head = [1,2], pos = 0 输出:true 解释:链表中有一个环,其尾部连接到第一个节点。 示例 3: 输入:head = [1], pos = -1 输出:false 解释:链表中没有环。 进阶: 你能用 O(1)(即,常量)内存解决此问题吗?
题解思路
遍历链表,将访问过的结点值修改为 Max_Value,直到遇到一个 Max_Value 或null,返回 true 或 false.
/**
* 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 || head.next==null)
return false;
int tmp=Integer.MAX_VALUE;
head.val=tmp;
while(head.next!=null){
if(head.next.val!=tmp){
head.next.val=tmp;
head=head.next;
}
else
return true;
}
return false;
}
}
提交记录
这种方法破坏了链表的原有数据,但是它快
利用 Set< ListNode >集,将访问过的 ListNode 存入其中,直到发现 contains 为true 或 null,返回答案
/**
* 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 || head.next==null)
return false;
Set<ListNode> s=new HashSet<>();
while(head.next!=null){
if(s.contains(head))
return true;
else{
s.add(head);
head=head.next;
}
}
return false;
}
}
提交记录
如果存在环形链表,则快指针(一次走两步),一定会追上慢指针(一次走一步),否则,快指针将会碰到 null。由此解题
/**
* 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 || head.next==null)
return false;
ListNode slow=head;
ListNode fast=head.next;
while(fast!=slow){
if(fast==null || fast.next==null)
return false;
fast=fast.next.next;
if(fast==slow) //这里多判断一次会更快
return true;
slow=slow.next;
}
return true;
}
}