1、很多成對出現(xiàn)的正整數保存在磁盤文件中,注意成對的數字不一定是相鄰的,如2,3,4,3,4,2...,由于意外有一個數字消失了,如何盡快找到是哪個數字消失了?
思路:考慮“異或”做操的定義,檔兩個操作數的對應位不相同時,該數的對應位就為1。也就是說如果是相等的兩個數“異或”,得到的結果為0,而0與任何數字“異或”,得到的是哪個數字本身。所以我們考慮將所有的數字做“異或”操作,因為只有一個數字消失,那么其他兩兩出現(xiàn)的數字“異或”后為0,0與僅有的一個數字做“異或”,我們就得到了消失的數字是哪個。
func findLostNum(nums: [UInt]) -> UInt {
var lostNum: UInt = 0
for num in nums {
lostNum = lostNum ^ num
}
return lostNum
}
2、如果有兩個數字意外丟失了(丟失的不是相等的數字),該如何找到丟失的兩個數字?
思路:設題目中這兩個只出現(xiàn)1次的數字分別為A和B,如果將A,B分開到兩個數組中,那顯然符合“異或”解法的關鍵點了。因此這個題目的關鍵點就是將A,B分開到兩個數組中。由于A,B肯定是不相等的。因此在二進制上必定至少有一位是不同的。根據這一位是0還是1可以將A和B分開到A組和B組。而這個數組中其他數字要么屬于A組,要么就屬于B組。再對A組和B組分別執(zhí)行“異或”解法就可以得到A,B了。而要判斷A,B在那一位上不相同,只要根據"A異或B"的結果就可以知道了,這個結果在二進制上為1的位都說明A,B在這一位上是不相同的。
func findTwoLostNum(nums: [UInt]) -> (UInt, UInt) {
var lostNum1: UInt = 0
var lostNum2: UInt = 0
/// 計算兩個數的異或結果
var tmp: UInt = 0
for num in nums {
tmp = tmp ^ num
}
/// 找到第一個為1的位
var flag: UInt = 1
while (tmp & flag) == 0 {
flag = flag << 1
}
/// 找兩個丟失的數字
for num in nums {
if (num & flag == 0) {
lostNum1 = lostNum1 ^ num
} else {
lostNum2 = lostNum2 ^ num
}
}
return (lostNum1, lostNum2)
}