位運算解決“一個數組中,只有一個數字出現n次,其他數字出現k次”問題


轉自:https://blog.csdn.net/monster_girl/article/details/52928864

在學習完位操作后,經常會遇到一類關於查找缺失整數的問題。
第一類是給你一個數組,告訴你這些數字的范圍是什么,然后讓你查找這個缺失的數字(例如無序數組的范圍是從1到10,不重復的9個數)。
這類問題的解決方法比較多樣,第一種,因為給定了范圍可以通過計算數字總和值,然后分別減去這些數字,剩下的則是缺失的數字。第二種,對這個數組進行排序,遍歷整個數組,然后判斷相鄰的元素是否連續,如果是,那缺失的數字則在兩段;如果不連續,中間缺少的則是需要查找的。

第二類還是給你一個數組,然后這些數字都出現了偶數次,只有一個數字出現了奇數次,讓你查找這個奇數次的數字,例如( 1, 2, 3, 4, 1, 2, 3)。

思路:通過一種運算,讓相同的元素在進行運算后可以相互消除,最后剩下的元素則是尋找的元素。這種位運算就是“異或”。通過異或,相同的數所有位都是0,而單獨的那個數則是它本身。

當題目條件發生改變,這個數組的數字可能出現了多次,但還是只有一個數字出現了一次,查找這個數字(假設在這里是出現了3次)。

思路:對於整數32位,對於每一位,整個數組的數加起來去除3的余數,就是在該元素在此位上的值。

總結:當一個數組有一個數恰好出現了k次,都可以用這個方法來解決。利用合適的位運算符將每一位保存,然后在找出這一位原來的數字。

第三類將難度又提升了,還是給你一個數組,里面的數字還是成對出現的,但單獨出現的數字變成了兩個,查找這兩個數字。

思路:還是可以運用位運算的,將這個數組分成兩部分,每一部分包含一個只出現一次的整數,這樣子題目就和第二類差不多了。具體步驟是先對數組的每一個元素進行異或,得到的是兩個數異或的結果,在這個結果中至少包含一個二進制位是1。

總結:任意選擇一個二進制位,然后將數組分成兩部分,其中一部分的末位是1,另一部分是0。由於這兩個單獨的數末位肯定不一樣,所以分組后肯定不會在同一個組內。這個問題的解決思路就和上面比較相似了。

從上面的幾個例子可以看出,查找缺失的數字主要是通過位運算符來抵消滿足條件的元素


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM