本文共 2039 字,大约阅读时间需要 6 分钟。
环形数组循环问题需要判断数组中是否存在符合条件的循环。循环的定义是从同一个起始点出发,经过若干步后回到起始点,且循环长度大于1,同时循环中的所有移动必须是同方向的。以下是详细的分析和解决方案。
给定一个环形数组 nums,其中包含正整数和负整数。每个元素 k 表示移动的步数,正数表示向前移动,负数表示向后移动。我们需要检测是否存在一个循环,使得从某个起始点出发,经过若干步后回到起始点,且循环长度 > 1,同时所有移动方向一致。
为了检测循环,我们可以使用快慢指针技术:
getNext:计算当前索引的下一个索引,确保环形处理。true。const circularArrayLoop = function(nums) { const n = nums.length; if (n === 0) return false; const getNext = (x) => { const next = (x + nums[x]) % n; return next < 0 ? next + n : next; }; for (let i = 0; i < n; i++) { if (nums[i] === 0) continue; let slow = i; let fast = getNext(i); while (true) { // 检查当前元素和下一个元素的符号是否相同 if (nums[slow] * nums[fast] <= 0) break; // 检查下一个元素和它的下一个元素的符号是否相同 if (nums[fast] * nums[getNext(fast)] <= 0) break; // 如果慢指针和快指针相遇,判断是否形成循环 if (slow === fast) { if (slow === getNext(slow)) { // 循环长度为1,不符合条件 break; } else { // 检查是否所有元素都在同一个循环中 let tmp = slow; let prev = slow; let count = 1; while (tmp !== prev) { tmp = getNext(tmp); if (nums[tmp] * nums[prev] <= 0) break; prev = tmp; count++; } if (count > 1) return true; } } slow = getNext(slow); fast = getNext(getNext(fast)); } // 剪枝处理,从i开始的所有元素置0 let tmp = i; let val = nums[tmp]; while (val !== 0) { nums[tmp] = 0; tmp = getNext(tmp); val = nums[tmp]; } } return false;}; getNext 函数:计算当前索引的下一个索引,使用模运算处理环形数组。通过上述步骤,可以有效检测环形数组中是否存在符合条件的循环。
转载地址:http://apckz.baihongyu.com/