สมมติว่าเรามีจำนวนอาร์เรย์วงกลมของค่าจำนวนเต็มบวกและลบ หากตัวเลข k ที่ดัชนีเป็นจำนวนบวก ให้ก้าวไปข้างหน้า k ขั้น มิฉะนั้น หากเป็นค่าลบ (-k) ให้เลื่อนถอยหลัง k ขั้น เนื่องจากอาร์เรย์เป็นวงกลม เราสามารถสรุปได้ว่าองค์ประกอบถัดไปขององค์ประกอบสุดท้ายคือองค์ประกอบแรก และองค์ประกอบก่อนหน้าขององค์ประกอบแรกคือองค์ประกอบสุดท้าย เราต้องตรวจสอบว่ามีการวนซ้ำ (หรือรอบ) ใน nums หรือไม่ รอบจะต้องเริ่มต้นและสิ้นสุดที่ดัชนีเดียวกันและความยาวของวงจร> 1 ดังนั้นหากอินพุตเป็นเช่น [2,-1,1,2,2] ผลลัพธ์จะเป็นจริงเนื่องจากมีวงจรจากดัชนี 0 -> 2 -> 3 -> 0 ของความยาว 3
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
n :=ขนาดของ nums
-
ถ้า n <2 ให้คืนค่าเท็จ
-
สำหรับฉันในช่วง 0 ถึง n - 1, nums[i] :=nums[i] mod n
-
สำหรับฉันอยู่ในช่วง 0 ถึง n – 1
-
ถ้า nums[i] =0 ให้ทำซ้ำต่อไป
-
ช้า =ฉัน, เร็ว =ฉัน;
-
ในขณะที่ nums[slow] * nums[fast]> 0 และ nums[next of fast] * nums[slow]> 0
-
ช้า =ถัดจากช้า
-
เร็ว :=ถัดไปของเร็ว
-
ถ้าช้า =เร็ว แล้ว
-
ถ้าช้า =ถัดไปของช้า ก็ออกมาจากลูป
-
คืนความจริง
-
-
-
x :=nums[i]
-
ช้า :=ฉัน
-
ในขณะที่ nums[ช้า] * x> 0
-
temp :=ถัดไปของช้า
-
ช้าต่อไป :=0
-
ช้า :=อุณหภูมิ
-
-
-
คืนค่าเท็จ
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h> using namespace std; class Solution { public: int next(vector<int>& nums, int i){ int n = nums.size(); return (n+nums[i]+i)%n; } bool circularArrayLoop(vector<int>& nums) { int n = nums.size(); if(n < 2) return false; for(int i = 0; i < n; i++)nums[i] %= n; for(int i = 0; i < n; i++){ if(nums[i] == 0) continue; int slow = i; int fast = i; while(nums[slow] * nums[fast] > 0 && nums[next(nums, fast)] * nums[slow] > 0){ slow = next(nums, slow); fast = next(nums, next(nums, fast)); if(slow == fast){ if(slow == next(nums, slow)) break; return true; } } int x = nums[i]; slow = i; while(nums[slow] * x > 0){ int temp = next(nums, slow); nums[slow] = 0; slow = temp; } } return false; } }; main(){ vector<int> v = {2,-1,1,2,2}; Solution ob; cout << (ob.circularArrayLoop(v)); }
อินพุต
[2,-1,1,2,2]
ผลลัพธ์
1