演算法 只出現一次的數字

2021-10-05 02:23:17 字數 2512 閱讀 9857

1. leetcode136

給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。

要求時間複雜度o(n),空間複雜度o(1)。

示例:輸入[4, 1, 2, 1, 2],輸出4

(1)面試官不想要的答案:建字典、排序。

(2)面試官想要的答案:位運算。

思路:如果我們對 0 和二進位制位做 xor 運算,得到的仍然是這個二進位制位,a^0=a

如果我們對相同的二進位制位做 xor 運算,返回的結果是 0,a^a=0

xor 滿**換律和結合律,a^b^a=a^a^b=0^b=b(位運算都滿**換律)

所以我們只需要將所有的數進行 xor 操作,得到那個唯一的數字。

class solution(object):

def singlenumber(self, nums):

""":type nums: list[int]

:rtype: int

"""a = 0

for i in nums:

a ^= i

return a

2. leetcode137

給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現了三次。找出那個只出現了一次的元素。

示例:輸入: [0,1,0,1,0,1,99],輸出: 99

思路:表面上,上面那題是兩個相等的數取異或得到了0,就剩下了只出現一次的數。實際上是1+1=0也就是二進位制運算只取了一位。所以如果要三個數字運算後為0,就是1+1+1=0,也就是三進製。

從位運算角度看,要求達到:01?01=10,10?01=00,所以可得01^01=10, 10&01=00。

使用a,b分別記錄2位。

b = b xor x & ~a;

a = a xor x & ~b;

abx

new_a

new_b00

1010

1110

1010

0000

0001

0011

0010

a的卡諾圖:

x\ab

0001

111000

0x11

01x0

b的卡諾圖:

x\ab

0001

111000

1x01

10x0

有:(~x&a&b)|(~x&a&~b)=~x&a        

(x&~a&b)|(x&a&b)=x&b

(~x&~a&b)|(~x&a&b)=~x&b

x&~a&~b

於是有a=(~x&a)|(x&b)

b=(~x&b)|(x&~a&~b)

class solution(object):

def singlenumber(self, nums):

""":type nums: list[int]

:rtype: int

"""a=0

b=0tmp=0

for i in nums:

tmp=a

a=((~i)&a)|(i&b)

b=((~i)&b)|(i&(~tmp)&(~b))

return b

由於**的實現中,每一位的計算並不是並行進行的,所以可以通過畫乙個行列由a,new_b,x構成的卡諾圖來利用先生成的位。

得到b=(~x&b)|(x&a)

只出現一次數字通解:

統計所有數字中每個位中1出現的總數,那麼對於某個位,1出現的次數一定是3的倍數或者是1或者0,那麼對這個數%3得到的結果就是目的數字在該位上的值。

class solution 

ans ^= (sum % 3) << i; // 還原到第i位

}return ans;

}};

3. leetcode260

給定乙個整數陣列nums,其中恰好有兩個元素只出現一次,其餘所有元素均出現兩次。 找出只出現一次的那兩個元素。

示例:把原陣列分成兩組,只出現過一次的兩個數字分別在兩組裡邊,那麼問題就轉換成之前的老問題了,只需要這兩組裡的數字各自異或,答案就出來了。

那麼通過什麼把陣列分成兩組呢?

放眼到二進位制,我們要找的這兩個數字是不同的,所以它倆至少有一位是不同的,所以我們可以根據這一位,把陣列分成這一位都是 1 的一類和這一位都是 0 的一類,這樣就把這兩個數分到兩組裡了。

那麼怎麼知道那兩個數字哪一位不同呢?

回到我們異或的結果,如果把陣列中的所有數字異或,最後異或的結果,其實就是我們要找的兩個數字的異或。而異或結果如果某一位是 1,也就意味著當前位兩個數字乙個是 1 ,乙個是 0,也就找到了不同的一位。

思路就是上邊的了,然後再考慮**怎麼寫。

只出現一次的數字

1.乙個整型陣列,有乙個數字出現一次,其餘數字出現兩次,找出這個只出現一次的數字。解題思路 異或運算性質 兩個相同的數字異或得0,0與乙個數字異或得數字本身,而且異或運算是滿足交換律的 陣列元素按位異或,交換律可以想象成相同的數字參與運算的時候是相鄰的 所有出現兩次的數字異或之後得0,最後剩餘的是0...

只出現一次的數字

給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。說明 你的演算法應該具有線性時間複雜度。你可以不使用額外空間來實現嗎?示例 1 輸入 2,2,1 輸出 1示例 2 輸入 4,1,2,1,2 輸出 4核心思想 對list排序,然後遍歷 class ...

只出現一次的數字

給定乙個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素 例 1,2,2 1 方法一 異或 數字1 數字2 每一位如果相同就為0,不同為1 1 1 0 1 0 1 0 1 1 0 0 0 class solution def singlenumber se...