給定乙個陣列a[0…n-1],找到從1開始,第乙個不在陣列中的正整數。
如3,5,1,2,-3,7,14,8輸出4
思路:將找到的元素放到正確的位置上,如果最終發現某個元素一直沒有找到,則該元素即為所求。
迴圈不變式:如果某命題初始為真,且每次更改後仍然保持該命題為真,則若干次更改後該命題仍然為真。
為表述方便,下面的演算法描述從1開始數
利用迴圈不變式設計演算法
假定前i-1個數已經找到,並且依次存放在a[1,2,…,i-1]中,繼續考察a[i]:
若a[i]<i且a[i]≥1,則a[i]在a[1,2,…,i-1]中已經出現過,可以直接丟棄。
若a[i]為負,則更應該丟棄它。
若a[i]>i且a[i]≤n,則a[i]應該位於後面的位置上,則將a[a[i]]和a[i]交換。
若a[i]≥n,由於缺失資料一定小於n,則a[i]丟棄。
若a[i]=i,則a[i]位於正確的位置上,則i加1,迴圈不變式擴大,繼續比較後面的元素
整理演算法描述:
若a[i]<i或者a[i]>n,則丟棄a[i]
若a[i]>i,則將a[a[i]]和a[i]交換。
若a[i]=i,i加1,繼續比較後面的元素。
思考:如何快速丟棄a[i]?
將a[n]賦值給a[i],然後n減1。
def first_missing_number(li):
size = len(li)
li.insert(0, none) # 為了方便從1開始數,在陣列前面新增none佔位
i = 1
while i <= size:
if li[i] < i or li[i] > size:
li[i] = li[size]
size -= 1
elif li[i] > i:
# 交換
temp = li[i]
li[i] = li[temp]
li[temp] = temp
else:
i += 1
return i
if __name__ == '__main__':
li = [3, 5, 1, 2, -3, 7, 14, 8]
result = first_missing_number(li)
print(result)
第乙個缺失的正整數 leetcode
為什麼不能nums這樣賦值呢?nums nums i nums i 呢 例如 如果陣列中存在3 那麼我們可不可以nums 3 3呢?這樣最後的結果會不會和 0,1,2,3,4,5 嗎?然後對這個陣列從1開始遍歷不就好了嗎這樣做事不行的,因為 1,2,3,0 這樣最後的結果就是 1,1,0,3 因為值...
Leetcode41 缺失的第乙個正整數
question 給你乙個未排序的整數陣列 nums 請你找出其中沒有出現的最小的正整數。高階 你可以實現時間複雜度為 o n 並且只使用常數級別額外空間的解決方案嗎?leetcode 41 資料範圍 0 n ums.leng th 300 0 nums.length 300 0 n ums.len...
第乙個缺失的整數
第乙個缺失的整數 給定乙個長度為n的陣列a 0,n 1 從1開始,找到第乙個不在陣列中的正整數。如 3,9,8,1,6,32 輸出為2。思路 求解該問題可以有三種策略,分別是暴力破解法 bitmap法和迴圈不變式方法。方法1 暴力破解法 看到這個題後,既然是找從1開始第乙個不在陣列a中的正整數,那最...