標記法 缺失數字 力扣(LeetCode)

2021-10-02 13:10:13 字數 1810 閱讀 2785

給定乙個包含0, 1, 2, ..., n中 n 個數的序列,找出 0 .. n 中沒有出現在序列中的那個數。

示例 1:

輸入:[3,0,1]輸出:2
示例 2:

輸入:[9,6,4,2,3,5,7,0,1]輸出:8
說明:

你的演算法應具有線性時間複雜度。你能否僅使用額外常數空間來實現?

看到這個題的第乙個思路是標記法,之前在那好像看見過,具體出處忘了了。

題意分析:題中n個元素取值為[0, n],且n個元素都不會重複,問題是讓我們找到非負的元素。我們可以利用元素本身都是非負性,我們可以將存在的元素num,其下標對應的元素變成負的(0的負數仍為其本身,需特殊處理),即nums[abs[num]] = -nums[abs[num]]

/*

用value的正負來做標記,nums[idx]為負表示idx出現在序列中

*/class

solution

for(

int i =

0; i < len +1;

++i)

if(nums[i]==0

)}if(

!flag)

return res;}}

;

參考leetcode題解,題解2是求和的方法,題解3是異或的方法。

求和法。從[0, n]中取n個元素,總和為n∗(

n+1)

2\frac

2n∗(n+

1)​,減去選取元素之和,得到的就是缺失的元素。

/*

求和法求和,再減去所選元素之和

*/class

solution

res = sum;

return res;}}

;

高斯求和明顯有溢位風險

所以有人對求和法進行了改進

直覺首先想到了數學方法,只需要遍歷一遍陣列,在把0-n這n個自然數全加起來的同時也減去nums[i],這樣不但效率高,也防止了資料溢位

/*

求和法求和,再減去所選元素之和

*/class

solution

res = sum;

return res;}}

;

既然可以先求和再減,那麼只要先編碼解碼,採用兩個互逆的操作,便可以找到缺失的元素。乘法和除法是兩個互逆的操作,但用到這題溢位的可能性更大。異或也是個可逆操作。如

n um

3=nu

m1⊕n

um2n

um1=

num3

⊕num

2\begin num3 = num1 \oplus num2 \\ num1 = num3 \oplus num2 \end

num3=n

um1⊕

num2

num1

=num

3⊕nu

m2​

/*

異或法*/

class

solution

res = sum;

return res;}}

;

力扣(LeetCode)缺失數字 個人題解

給定乙個包含0,1,2,n中 n 個數的序列,找出 0 n 中沒有出現在序列中的那個數。示例 1 輸入 3,0,1 輸出 2示例 2 輸入 9,6,4,2,3,5,7,0,1 輸出 8說明 你的演算法應具有線性時間複雜度。你能否僅使用額外常數空間來實現?思路有兩種,一種是求和,根據數學方法算出缺失項...

力扣日記 268 缺失數字 位運算

給定乙個包含 0,1,2,n 中 n 個數的序列,找出 0 n 中沒有出現在序列中的那個數。示例 1 輸入 3,0,1 輸出 2 示例 2 輸入 9,6,4,2,3,5,7,0,1 輸出 8 說明 你的演算法應具有線性時間複雜度。你能否僅使用額外常數空間來實現?class solution def ...

力扣 簡單的數字反轉

給出乙個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。示例 1 輸入 123輸出 321注意 假設我們的環境只能儲存得下 32 位的有符號整數,則其數值範圍為 231,231 1 請根據這個假設,如果反轉後整數溢位那麼就返回 0。這是錯誤的 int reverse int x lo...