457 環形陣列迴圈

2021-09-13 01:35:53 字數 2101 閱讀 5514

給定一組含有正整數和負整數的陣列。如果某個索引中的 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 中是否存在迴圈 或週期 迴...