array
two pointers
hash table
]
Leetcode 0457 Circular Array Loop
Problem statement
https://leetcode.com/problems/circular-array-loop/
Solution
First of all, if we have numbers >= n, make them in range (-n+1, n-1). Now, let us iterate over list and start to build loop, and save direction of movement. I denote visited elements by n + i. So, if we find new element with this value, we return True. If we found 0 or number in range (n, n + i), we break our loop: it means we found already visited elements. If direction is wrong, we also break.
Complexity
Time complexity is O(n), additional space is O(1), because we directly change our nums.
Code
class Solution:
def circularArrayLoop(self, nums):
def sign(q): return q/abs(q)
n = len(nums)
for i in range(n):
nums[i] = int(sign(nums[i]) * (abs(nums[i]) % n))
for i in range(n):
if nums[i] == 0 or nums[i] >= n: continue
dr, start = sign(nums[i]), i
while True:
tmp = nums[start]
nums[start] = n + i
start = (start + tmp) % n
if nums[start] == n + i: return True
if nums[start] == 0 or nums[start] in range(n, n + i): break
if sign(nums[start]) != dr: break
There is similar solution, using the idea of Problem 0141 Linked List Cycle: we use two iterators: fast and slow. If there is a loop (fast == slow), we return true, else if we meet element with different directions, then the search fail, we set all elements along the way to 0. Because 0 is fail for sure so when later search meet 0 we know the search will fail.