41. First Missing Positive 缺失的第一个正数
Title
給你一個未排序的整數數組,請你找出其中沒有出現的最小的正整數。
示例 1:
輸入: [1,2,0]
輸出: 3
示例 2:
輸入: [3,4,-1,1]
輸出: 2
示例 3:
輸入: [7,8,9,11,12]
輸出: 1
提示:
你的算法的時間復雜度應為O(n),并且只能使用常數級別的額外空間。
哈希表
Solve
我們可以將數組所有的數放入哈希表,隨后從1開始依次枚舉正整數,并判斷其是否在哈希表中。
如果數組的長度為N,那么第一種做法的時間復雜度為O(N),空間復雜度為O(N)。
我們為什么要使用哈希表?
因為哈希表是一個可以支持快速查找的數據結構:給定一個元素,可以在O(1)的時間查找該元素是否在哈希表中。
因此,我們可以考慮將給定的數組設計成哈希表的【替代產品】。
實際上,對于長度為N的數組,其中沒有出現的最小正整數只能在[1, N+1]中,這樣以來,我們將所有在[1, N]范圍內的數放入哈希表,也可以得到最終的答案,而給定的數組恰好長度為N,這讓我們有了一種將數組設計成哈希表的思路:
我們對數組進行遍歷,對于遍歷到的數 x,如果它在 [1, N] 的范圍內,那么就將數組中的第 x-1 個位置(注意:數組下標從 0 開始)打上「標記」。在遍歷結束之后,如果所有的位置都被打上了標記,那么答案是 N+1,否則答案是最小的沒有打上標記的位置加 1。
由于數組中的數沒有任何限制,因此這并不是一件容易的事情。但我們可以繼續利用上面的提到的性質:由于我們只在意 [1, N] 中的數,因此我們可以先對數組進行遍歷,把不在 [1, N] 范圍內的數修改成任意一個大于 N 的數(例如 N+1)。這樣一來,數組中的所有數就都是正數了,因此我們就可以將「標記」表示為「負號」。算法的流程如下:
Code
def firstMissingPositive(self, nums: List[int]) -> int:length = len(nums)for i in range(length):if nums[i] <= 0:nums[i] = length + 1for i in range(length):num = abs(nums[i])if num <= length:nums[num - 1] = -abs(nums[num - 1])for i in range(length):if nums[i] > 0:return i + 1return length + 1復雜度分析
時間復雜度:O(N),其中 N 是數組的長度。
空間復雜度:O(1)。
置換
Solve
將給定的數組「恢復」成下面的形式:如果數組中包含 x∈[1,N],那么恢復后,數組的第 x - 1 個元素為 x。
在恢復后,數組應當有[1, 2, …, N]的形式,但其中有若干個位置上的數是錯誤的,每一個錯誤的位置就代表了一個缺失的正數。
以題目中的示例二 [3, 4, -1, 1] 為例,恢復后的數組應當為 [1, -1, 3, 4],我們就可以知道缺失的數為 2。
那么我們如何將數組進行恢復呢?我們可以對數組進行一次遍歷,對于遍歷到的數x=nums[i],如果 x∈[1,N],我們就知道 x 應當出現在數組中的 x - 1 的位置,因此交換nums[i] 和 nums[x?1],這樣 x 就出現在了正確的位置。
在完成交換后,新的 nums[i] 可能還在 [1,N] 的范圍內,我們需要繼續進行交換操作,直到 x ? [1,N]。
注意到上面的方法可能會陷入死循環。如果 nums[i] 恰好與 nums[x?1] 相等,那么就會無限交換下去。
因此在這種情況下,x 本就已經出現在了正確的位置,只是數組里面有多個 x 而已。因此我們就不需要進行交換,而是開始遍歷下一個數。
由于每次的交換操作都會使得某一個數交換到正確的位置,因此交換的次數最多為 N,整個方法的時間復雜度為 O(N)。
Code
def firstMissingPositive(self, nums: List[int]) -> int:length = len(nums)for i in range(length):while 1 <= nums[i] <= length and nums[nums[i] - 1] != nums[i]:nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]for i in range(length):if nums[i] != i + 1:return i + 1return length + 1復雜度分析
時間復雜度:O(N),其中 N 是數組的長度。
空間復雜度:O(1)。
總結
以上是生活随笔為你收集整理的41. First Missing Positive 缺失的第一个正数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试题 02.01. 移除重复节点
- 下一篇: 209. Minimum Size Su