141. 环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
题解:
1)hash
2)双指针
sloution:
1)hash
public class Solution {
public boolean hasCycle(ListNode head) {
HashMap<ListNode,Integer> map =new HashMap<>();
while(head!=null){
if(map.get(head)==null) map.put(head,1);
else return true;
head=head.next;
}
return false;
}
}
2)
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null) {
return false;
}
ListNode slow = head;
ListNode fast = head.next;
while (fast != null && fast.next != null) {
if (slow.equals(fast)) {
return true;
}
slow = slow.next;
fast = fast.next.next;
}
return false;
}
}
142. 环形链表 II(寻找入环节点)
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
题解:
1)hashset
2)快慢指针:head到入环第一个结点的距离等于两指针重合处到入环第一个结点的剩余环形距离。 即若有两个慢指针同时分别从链表头结点和快慢指针第一次相遇的节点出发, 两者必然会在入环节点相遇。
利用寻找链表的入环节点的思想, 把数组当成对链表的一种描述, 数组里的每一个元素的值表示链表的下一个节点的索引
如示例1中的[1, 3, 4, 2, 2]
把数组索引为0的元素当成链表的头节点
索引为0的元素的值为1, 表示头节点的下一个节点的索引为1, 即数组中的3
再下一个节点的索引为3, 即为第一个2
再下一个节点的索引为2, 即为4
再下一个节点的索引为4, 即为第二个2
再下一个节点的索引为2, 即为4 此时形成了一个环
而形成环的原因是下一节点的索引一致, 即为重复的数字
sloution:
1)
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> set=new HashSet<ListNode>();
ListNode node =head;
while(node!=null){
if(set.contains(node)) return node;
set.add(node);
node=node.next;
}
return null;
}
}
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head, 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;
while(slow != head) {
head = head.next;
slow = slow.next;
}
return slow;
}
}