LeetCode 41 缺失的第乙個正數

2021-09-29 05:59:47 字數 2393 閱讀 4901

題目描述:

給定乙個未排序的整數陣列,找出其中沒有出現的最小的正整數。

示例 1:

輸入:[1

,2,0

]輸出:

3

示例 2:

輸入:[3

,4,-

1,1]

輸出:2

示例 3:

輸入:[7

,8,9

,11,12

]輸出:

1

方法 1:索引作為雜湊表。

資料預處理

首先我們可以不考慮負數和零,因為不需要考慮。同樣可以不考慮大於 n 的數字,

因為首次缺失的正數一定小於或等於 n + 1 。

缺失的正數為 n + 1 的情況會單獨考慮。

為了不考慮這些數,又要保證時間複雜度為 o(n) ,因此

不能將這些元素彈出。我們可以將這些數用 1 替換。

為了確保缺失的第乙個正數不是 1,先要在這步操作前確定 1 是否存在。

如何實現就地演算法

現在我們有乙個只包含正數的陣列,範圍為 1 到 n,

現在的問題是在o(n) 的時間和常數空間內找出首次缺失的正數。

如果可以使用雜湊表,且雜湊表的對映是 正數 -> 是否存在 的話,這其實很簡單。

「髒工作環境」 的解決方法是將乙個字串 hash_str 分配 n 個 0,並且用類似於雜湊表的方法,如果在陣列**現數字 i 則將字串中 hash_str[i] 修改為 1 。

我們不使用這種方法,但是借鑑這種 使用索引作為雜湊鍵值 的想法。

最終的想法是 使用索引作為雜湊鍵 以及 元素的符號作為雜湊值 來實現是否存在的檢測。

例如,nums[2] 元素的負號意味著數字 2 出現在 nums 中。nums[3]元素的正號表示 3 沒有出現在 nums 中。

為了完成此操作,我們遍歷一遍陣列(該操作在資料預處理使得陣列中只有正數的操作後),檢查每個元素值 elem 以及將nums[elem] 元素的符號變為符號來表示數字 elem 出現在 nums 中。注意,當數字出現多次時需要保證符號只會變化 1 次。

演算法

現在可以開始寫演算法了。

檢查 1 是否存在於陣列中。如果沒有,則已經完成,1 即為答案。

如果 nums = [1],答案即為 2 。

將負數,零,和大於 n 的數替換為 1 。

遍歷陣列。當讀到數字 a 時,替換第 a 個元素的符號。

注意重複元素:只能改變一次符號。由於沒有下標 n ,使用下標 0 的元素儲存是否存在數字 n。

再次遍歷陣列。返回第乙個正數元素的下標。

如果 nums[0] > 0,則返回 n 。

如果之前的步驟中沒有發現 nums 中有正數元素,則返回n + 1。

**(官方題解,看不懂。。。)

class

solution}if

(contains==0)

return1;

if(n==1)

return2;

// 用 1 替換負數,0,

// 和大於 n 的數

// 在轉換以後,nums 只會包含

// 正數

for(

int i=

0;i)// 使用索引和數字符號作為檢查器

// 例如,如果 nums[1] 是負數表示在陣列**現了數字 `1`

// 如果 nums[2] 是正數 表示數字 2 沒有出現

for(

int i =

0; i < n; i++

)// 現在第乙個正數的下標

// 就是第乙個缺失的數

for(

int i =

1; i < n; i++)if

(nums[0]

>0)

return n;

return n +1;

}}

leetcode 41 缺失的第乙個正數

給定乙個未排序的整數陣列,找出其中沒有出現的最小的正整數。示例 1 輸入 1,2,0 輸出 3 示例 2 輸入 3,4,1,1 輸出 2 示例 3 輸入 7,8,9,11,12 輸出 1 說明 你的演算法的時間複雜度應為o n 並且只能使用常數級別的空間。題目規定了時間複雜度為o n 空間複雜度為常...

LeetCode 41 缺失的第乙個正數

給定乙個未排序的整數陣列,找出其中沒有出現的最小的正整數。示例 1 輸入 1 2,0 輸出 3示例 2 輸入 3 4,1,1 輸出 2示例 3 輸入 7 8,9 11,12 輸出 1說明 這題確實挺坑的,首先對陣列排個序,當時想用陣列標記的,沒想到還有int max級別的數,不過vector應該是裝...

Leetcode 41 缺失的第乙個正數

給定乙個未排序的整數陣列,找出其中沒有出現的最小的正整數。示例 1 輸入 1,2,0 輸出 3示例 2 輸入 3,4,1,1 輸出 2示例 3 輸入 7,8,9,11,12 輸出 1說明 你的演算法的時間複雜度應為o n 並且只能使用常數級別的空間。這個題第乙個想法是排序,然後遍歷即可,但是時間複雜...