判断环形数组是否存在环--强行dfs记忆化 or 快慢指针解决

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了判断环形数组是否存在环--强行dfs记忆化 or 快慢指针解决相关的知识,希望对你有一定的参考价值。

题目

强行dfs解决(速度较慢)

class Solution {
public:
    bool circularArrayLoop(vector<int>& nums) {
        int n = nums.size();
        vector<int>dp(n);
        function<bool(int,int)> check = [&](int pre,int next){
            if((nums[pre]^nums[next])<0){
                return false;
            }
            if(dp[next]){
                if(next!=pre)
                    return true;
                return false;
            }
            dp[next] = 1;
            if(nums[next]<0){
                int nn = (next+nums[next]+n*100)%n;
                if(!check(next,nn)){
                    dp[next] = 0;
                        return false;
                }
            }else{
                int nn = (next+nums[next])%n;
               if(!check(next,nn)){
                   dp[next] = 0;
                        return false;
               }
            }
            return true;
};
        for(int i=0;i<n;i++){
            if(check(i,i))
                return true;
        }
        return false;
    }
};

dfs+记忆化解决(速度提升)

class Solution {
public:
    bool circularArrayLoop(vector<int>& nums) {
        int n = nums.size();
        vector<int>dp(n);
        function<bool(int,int)> check = [&](int pre,int next){
            if((nums[pre]^nums[next])<0){
                return false;
            }
            if(dp[next]==1){
                if(next!=pre)
                    return true;
                return false;
            }if(dp[next]==2)
                return false;
            dp[next] = 1;
            if(nums[next]<0){
                //每次失败回溯的时候标记状态为2
                int nn = (next+nums[next]+n*100)%n;
                if(!check(next,nn)){
                    dp[next] = 2;
                        return false;
                }
            }else{
                int nn = (next+nums[next])%n;
               if(!check(next,nn)){
                   dp[next] = 2;
                        return false;
               }
            }
            return true;
};
        for(int i=0;i<n;i++){
            if(check(i,i))
                return true;
        }
        return false;
    }
};

快慢指针解决(O(1)空间复杂度)

class Solution {
public:
    bool circularArrayLoop(vector<int>& nums) {
        int n = nums.size();
        auto next = [&](int cur) {
            return ((cur + nums[cur]) % n + n) % n; // 保证返回值在 [0,n) 中
        };

        for (int i = 0; i < n; i++) {
            if (!nums[i]) {
                continue;
            }
            int slow = i, fast = next(i);
            // 判断非零且方向相同
            while (nums[slow] * nums[fast] > 0 && nums[slow] * nums[next(fast)] > 0) {
                if (slow == fast) {
                    if (slow != next(slow)) {
                        return true;
                    } else {
                        break;
                    }
                }
                //fast走两步,slow走一步
                slow = next(slow);
                fast = next(next(fast));
            }
            int add = i;
            //一旦此次未出现合法的环,那么这些位置下一次碰到就可以continue了
            while (nums[add] * nums[next(add)] > 0) {
                int tmp = add;
                add = next(add);
                nums[tmp] = 0;
            }
        }
        return false;
    }
};

以上是关于判断环形数组是否存在环--强行dfs记忆化 or 快慢指针解决的主要内容,如果未能解决你的问题,请参考以下文章

判断环形数组是否存在循环

LeetCode 565 数组嵌套[dfs 记忆化] HERODING的LeetCode之路

判断无向图/有向图中是否存在环

区间型动态规划的记忆化搜索实现与环形动态规划的循环数组实现

判断链表中是否存在环表(Java版)

环形链表(哈希表链表)寻找两个正序数组的中位数(数组二分查找)二进制求和(位运算数学)