457. 环形数组是否存在循环

2021-08-09  本文已影响0人  漫行者_

https://leetcode-cn.com/problems/circular-array-loop/
题目意思有点饶,看了几遍才读懂。。
题解看了好久才完全看明白,特别是两个循环,以及为什么要这样做的初始化。
核心还是要理解快慢指针,

解题前:
判断是否有环的题目常见的思路就是快慢指针。

对于如何证明快慢指针:就是快指针在后面,一次走两步,慢指针在前,一次走一步。

问题1:怎么证明快慢指针一定会相遇:数学归纳法

当快指针落后慢指针1步时:显然同时走一步会相遇

当快指针落后慢指针2步时:显然同时走一步时候就变成落户1步的情况

假设当落后N步的时候,同时走N次一定相遇,

当落后N+1步的时候,同时走了N次,就说明只差一步,就到了第一种情况。

问题2:怎么证明只有一圈的情况

假设圈的点数为N个,快指针落后的点数必须要小于N个为n。

根据问题一的结论,就得走n次相遇,所以一圈就行。

解题中:
题目主要是有三个难点:

class Solution {
     int[] nums;
    int n;
    public boolean circularArrayLoop(int[] nums) {
        this.n = nums.length;
        this.nums = nums;
        // 保证有点出现在环内
        for(int i = 0; i < n; ++i){
            //实现前后脚达到圈内
            int slow = i, fast = next(i);
            while(nums[fast] * nums[slow] > 0 && nums[next(fast)] * nums[slow] > 0){
                if(fast == slow){
                    if(slow == next(slow)) break; // 存在长度k为1的同向环
                    else return true; // 否则满足要求
                }
                // 指针移动
                fast = next(next(fast));
                slow = next(slow);
            }
        }
        return false;
    }
    private int next(int i){
        // 注意java下标不能像python有负数,-1需要处理成n-1
        return ((i + nums[i]) % n + n) % n;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读