給定一組含有正整數和負整數的陣列。如果某個索引中的 n 是正數的,則向前移動 n 個索引。相反,如果是負數(-n),則向後移動 n 個索引。
假設陣列首尾相接。判斷陣列中是否有環。環中至少包含 2 個元素。環中的元素一律「向前」或者一律「向後」。
你能寫出時間複雜度為 o(n) 且空間複雜度為 o(1) 的演算法嗎?
給定陣列 [2, -1, 1, 2, 2], 有乙個迴圈,從索引 0 -> 2 -> 3 -> 0。
給定陣列[-1, 2], 沒有迴圈。
給定陣列保證不包含元素"0"。
此題若是沒有時間和空間複雜度的限制的話是非常簡單的。但是想要達到o(n)時間複雜度和o(1)空間複雜度就比較困難,看了別人寫的一些部落格,還沒有看到同時達到上述兩個要求的。
通過思考可以知道,想要在一邊迴圈中得到答案同時又保證o(1)的複雜度就要充分利用輸入的列表nums。對於nums的每個值我們至少要能獲得以下三個資訊:
是否是搜尋過的
是否是正在搜尋的
是否還未搜尋
由於0保證不包含在列表中,所以可以用0作為已經搜尋過且不存在環的標誌;在最開始先求出列表中絕對值最大的數k,再將每個正整數加k,每個負整數減k,這樣不在-k到k中的就可以作為還未搜尋的標誌;反之就是正在搜尋的。
解決了這個問題之後,還有乙個關鍵的問題。當某一次搜尋失敗時,如何將這一次搜尋過的元素改為0。如果通過遍歷就會導致時間複雜度提高,顯然不可以通過這樣粗暴的方式。於是便想到了指標的思想,當搜尋時,每乙個搜尋位置都儲存上乙個搜尋的位置資訊,這樣當搜尋失敗時,就可以沿著此資訊將所有此次搜尋的元素全部改為0。具體細節請參考以下**:
class solution(object):
def circulararrayloop(self, nums):
""":type nums: list[int]
:rtype: bool
"""k = len(nums)
if k > 1:
l = max([abs(max(nums)), abs(min(nums))])
for i in range(k):
if nums[i] > 0 :
nums[i] += l
else:
nums[i] -= l
for i in range(k):
if nums[i] > l and (nums[i] - l) % k != 0:
a = (nums[i] - l + i) % k #下一位置的索引
b = i #當前位置索引
nums[i] = -1
while nums[a] > l and (nums[a] - l) % k != 0:
c = nums[a]
nums[a] = b
b = a
a = (a + c - l) % k
if 0 < nums[a] <= l or nums[a] == -1:
return true
else:
while nums[b] != -1:
a = nums[b]
nums[b] = 0
b = a
nums[b] = 0
elif nums[i] < -l and (nums[i] + l) % k != 0:
a = (i + nums[i] + l) % k #下一位置的索引
b = i #當前位置索引
nums[i] = 1
while nums[a] < -l and (nums[a] + l) % k != 0:
c = nums[a]
nums[a] = b
b = a
a = (a + c + l) % k
if 0 < nums[a] <= l or nums[a] == 1:
return true
else:
while nums[b] != 1:
a = nums[b]
nums[b] = 0
b = a
nums[b] = 0
return false
457 環形陣列迴圈
給定乙個含有正整數和負整數的環形陣列nums。如果某個索引中的數 k 為正數,則向前移動 k 個索引。相反,如果是負數 k 則向後移動 k 個索引。因為陣列是環形的,所以可以假設最後乙個元素的下乙個元素是第乙個元素,而第乙個元素的前乙個元素是最後乙個元素。確定nums中是否存在迴圈 或週期 迴圈必須...
Leetcode 457 環形陣列迴圈
給定一組含有正整數和負整數的陣列。如果某個索引中的 n 是正數的,則向前移動 n 個索引。相反,如果是負數 n 則向後移動 n 個索引。假設陣列首尾相接。判斷陣列中是否有環。環中至少包含 2 個元素。環中的元素一律 向前 或者一律 向後 示例 1 給定陣列 2,1,1,2,2 有乙個迴圈,從索引 0...
Leetcode 457 環形陣列迴圈 C
給定乙個含有正整數和負整數的環形陣列 nums。如果某個索引中的數 k 為正數,則向前移動 k 個索引。相反,如果是負數 k 則向後移動 k 個索引。因為陣列是環形的,所以可以假設最後乙個元素的下乙個元素是第乙個元素,而第乙個元素的前乙個元素是最後乙個元素。確定 nums 中是否存在迴圈 或週期 迴...