成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

位運算的秒用--異或運算面試真題

開發 前端
一個數組中有一種數出現了奇數次,其他數都出現了偶數次,怎么找到這一個數,這是一道異或運算面試真題,今天就來跟大家聊聊如何解答這個問題。

前言

上次咱們聊了聊異或運算的妙用,其實簡單來說,就是記住異或運算的三個特性

  • 0和任何數N進行異或運算,結果為N。
  • 任何數N和自己進行異或運算,結果為0。
  • 異或運算滿足交換律和結合律 當然如果您對這幾個特性不是很了解,或者不是很熟悉異或運算的話,建議先看看這篇文章?? 位運算的妙用--異或運算??。

「閑話不用多說,咱們來看面試真題」

Q1:一個數組中有一種數出現了奇數次,其他數都出現了偶數次,怎么找到這一個數

「要求:時間復雜度O(n)」。

其實這道題還是比較好理解的。

咱們直接來舉例子。

比如數組[1,1,2,2,3] 把3找出來即可,因為3只出現了1次,為奇數次,其余的數字出現的都為偶數次。

比如數組[1,1,2,2,3,3,3] 同樣把3找出來即可。

其實最簡單的方法,也就是暴力破解法,咱們可以把數組循環一遍,把每個數字出現的數字記錄在另一個數組中(需要記錄數字和該數字出現的次數的map),然后循環另一個數組找出出現次數為奇數的即可。「但是這個題目有要求」,時間復雜度要求為O(n),也就是說只能循環一次就把結果就找出來,所以暴力破解法肯定是行不通的。所以咱們必須得換個思路。

利用異或運算的規律來解題

首先,在異或運算中「任何數N和自己進行異或運算,結果為0」,所以我們把數組中的所有數進行異或運算,所有「出現偶數次的數字進行異或運算結果為0」,咱們來看一個例子(因為異或運算滿足交換律,所以不用關心數字出現的位置)。

arr = [a,b,b,c,c,c,c,d,d.............]

比如看上述數組,咱們來對每個元素進行異或運算。

temp = a ^ b ^ b ^ c ^ c ^ c ^ c ^ d ^ d

因為「任何數N和自己進行異或運算,結果為0」所以除了a以外的數字,異或結果為0。

所以全部進行異或運算一次的結果為:

temp = a^0

其實簡單的說就是兩個b異或結果為0,兩個c異或結果是0(上面的case寫了4個c,其實結果是一樣的),兩個d異或結果為0,那么所有的數字異或下來,出現偶數次的結果異或運算的結果就為0。

另外根據「0和任何數N進行異或運算,結果為N」所以:

temp = a^0 = a

所以最終的temp則為我們需要找到的數,源碼如下:

func findOddTimesNumber(arr []int) (temp int) {
for i := 0; i < len(arr); i++ {
temp ^= arr[i] //temp默認為0 相當于0^a(出現奇數次的數字)^b^b^c^c.......,根據上述運算的解析,結果為a,也就是我們想找到的數
}
return temp
}

如果上面的題您已經明白了,那么「接下來咱們加大難度,看一種更復雜的情況」。

Q2:一個數組中有兩種數出現了奇數次,其他數都出現了偶數次,怎么找到這一個數

「要求:時間復雜度O(n)」。

這道題和上面那道題的區別就在于「有兩種數字出現了奇數次」。

arr = [a,b,c,c,d,d,e,e......]

其實簡單說也就是要把上面數組arr中的a和b分別找出來,如果按照前面的方法全部異或一次,那么結果肯定為a^b,我們的目的是把a和b分別找出來,這種辦法當然是行不通的,或者說是不夠的。

但是上面計算之后的結果:

temp= a^b(其余出現偶數次的數字進行異或運算結果都為0)

首先,因為a和b是兩種數,所以「a肯定是不等于b的」,所以「a^b的結果肯定大于0」,換句話說a^b的結果,也就是「temp的二進制表現肯定是至少有一位是1的」。這句話很重要,明白了這句話咱們就繼續往下看。

比如temp的第7位為1,那就說明a和b的第7位是不一樣的,一個為0,一個為1。那么咱們是不是可以通過第7位是否為1,然后進行分組,「每個分組中出現的偶數次的數字的異或結果都是0的」,所以最后兩個分組各自剩下的就是所需數字了。

咱們先來看一個方法。

res := num & (^num + 1)

上述方法的目的是獲取num最左邊的1。什么意思呢?比如num是 1011011,那么他最左邊的1 就是00000001。

咱們用一個代入的方式一步一步的計算試試。

所以最后算法如下:

func findTwoOddTimesNumber(arr []int) (left, right int) {
for i := 0; i < len(arr); i++ {
left ^= arr[i]
}
temp := left & (^left + 1) //獲取最左邊的1

for i := 0; i < len(arr); i++ {
if arr[i]&temp == 0 { //根據某一位是否為1進行分組
right ^= arr[i]
}
}
left = right ^ left
return left, right
}
責任編輯:姜華 來源: 程序員小飯
相關推薦

2022-05-18 16:06:15

位運算異或運算

2021-11-10 09:57:02

異或運算應用

2022-08-01 08:12:14

位運算代碼性能

2020-03-25 10:44:16

位運算操作技巧

2021-01-23 12:22:59

位運算編程語言開發

2021-02-21 06:36:57

運算技巧按位

2017-08-29 09:40:26

JavaScript代碼神經網絡

2021-10-11 09:41:20

React位運算技巧前端

2009-07-31 16:48:44

C#位運算

2011-08-29 15:53:04

Lua位運算

2018-05-21 20:45:45

2009-08-12 10:20:52

C#位運算符

2023-04-07 08:02:54

源碼位邏輯運算符

2024-06-11 14:57:00

2023-07-11 09:26:32

2009-06-18 13:06:59

C#位運算權限管理

2018-07-29 15:27:04

AI訓練光速運算人工智能

2009-08-12 10:47:03

C#運算符重載

2020-11-09 10:01:29

Python乘法位運算

2020-11-03 18:36:37

面試字符串算法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 好姑娘高清在线观看电影 | 一区二区久久 | 狠狠躁夜夜躁人人爽天天高潮 | 中文字幕一区二区三区乱码在线 | 黄色三级免费网站 | 91操操操| 国产精品揄拍一区二区 | 成人影院在线 | 精品久久久久久 | 成人免费精品视频 | 精品国产一区久久 | 国产精品一级在线观看 | 一区二区三区高清 | 五月综合激情网 | 91精品国产综合久久久久久丝袜 | 九九热在线免费视频 | 欧美日韩国产一区二区三区 | 男女视频91 | 久久久久国产精品一区 | 久久伦理中文字幕 | 成人av激情 | 九九福利 | 国内精品久久精品 | 97精品国产 | 亚洲一区av在线 | 国产精品a久久久久 | 天天干.com | 国产毛片视频 | 97国产在线观看 | 久久久999免费视频 999久久久久久久久6666 | 嫩草伊人| 成人a免费 | 精品国产精品国产偷麻豆 | 久久婷婷国产麻豆91 | 亚洲欧美中文日韩在线v日本 | 亚洲成人一区二区 | 在线观看视频福利 | 欧美aaaaaa| 久久久精品久久 | 少妇一区二区三区 | 91社区在线观看高清 |