141. 环形链表

141. 环形链表

  1. public class Solution {
  2. public boolean hasCycle(ListNode head) {
  3. if(head==null||head.next==null) return false;
  4. ListNode slow=head.next;
  5. ListNode fast=head.next.next;
  6. while(slow!=fast){
  7. if(fast==null||fast.next==null) return false;
  8. slow=slow.next;
  9. fast=fast.next.next;
  10. }
  11. return true;
  12. }
  13. }

142. 环形链表 II

142. 环形链表 II
假设环路开始的节点索引为a,循环的长度为loop(loop步,不是loop个节点)
第一阶段
fast一次走2步,slow一次走1步
fast和slow相遇的时候,一定都在循环里,fast可能已经走了N遍循环了,假设slow走到循环起点后走了x步相遇
2(a+x)=a+x+Nloop
可以得到x+a=N
loop
此时slow再走a步就可以走完循环回到循环的起点,如何得到a?
第二阶段:
把fast放回head一步一步走,走a步便会和slow在循环的起点相遇
最后结果返回循环的起点

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head==null||head.next==null) return null;
        ListNode slow=head.next;
        ListNode fast=head.next.next;
        while(slow!=fast){
            if(fast==null||fast.next==null) return null;
            slow=slow.next;
            fast=fast.next.next;
        }
        fast=head;
        while(slow!=fast){
            slow=slow.next;
            fast=fast.next;
        }
        return fast;
    }
}

287. 寻找重复数

287. 寻找重复数
与环形链表II思路相同
题目:给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。
可以知道对于数组中任意一个数num,nums[num]都没有越界,都有对应的值。
输入数组:nums = [1,3,4,2,2]
有两个2,nums[3]=2,nums[4]=2,节点3和节点4都指向2这个节点。
image.png
把数组看成一个链表,起点head=0,head.next=nums[0]
输入的数组可以形成一个环形链路,需要找到的重复数就是环路的起点。

class Solution {
    public int findDuplicate(int[] nums) {
        int fast=nums[nums[0]];
        int slow=nums[0];
        while(fast!=slow){
            fast=nums[nums[fast]];
            slow=nums[slow];
        }
        fast=0;
        while(fast!=slow){
            fast=nums[fast];
            slow=nums[slow];
        }
        return slow;
    }
}