两个数的交换
无符号整数二进制中1的个数
第一种解法:
循环遍历无符号整数二进制的每一位判断是否为1。
如果二进制中有较多的0,每次右移一位做出判断会很浪费
func countOfOnes(num: UInt) -> UInt {
var count: UInt = 0
var temp = num
while temp != 0 {
count += temp & 1
temp = temp >> 1
}
return count
}
第二种解法:
使用技巧num = num & (num - 1)
消去二进制中最低位的1。
如果最低位为1,num-1后相应位为0,相与之后为0;如果最低位为0,num-1向前借1,有1位则变为0,相与之后为0,则消去了最低位的1。
统计消去次数,便是二进制1的个数
func countOfOnes(num: UInt) -> UInt {
var count: UInt = 0
var temp = num
while (temp != 0) {
count = count + 1
temp = temp & (temp - 1)
}
return count
}
引申:如何判断一个整数为2的整数次幂
一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他位都是0,如果使用num = num & (num - 1)
消去最低位1后,num为0。即判断是否为0,即可判断是否为2的整数次幂。
func isPowerOfTwo(num: UInt) -> Bool {
return (num & (num - 1) == 0)
}
缺失的数字1
技巧:
0异或任何数为0,一个数异或自己为0
解法:
数组中的数成对出现,缺失一个数,将所有数异或起来便剩下缺失的数(其他所有成对的数异或为0)
func findLostNum(nums: [UInt]) -> UInt {
var lostNum: UInt = 0
for num in nums {
lostNum = lostNum ^ num
}
return lostNum
}
缺失的数字2
func findTwoLostNum(nums: [UInt]) -> (UInt, UInt) {
var lostNum1: UInt = 0
var lostNum2: UInt = 0
var temp: UInt = 0
//两个缺失数的异或
for num in nums {
temp = temp ^ num
}
var flag: UInt = 1
//将temp分为temp和flag的异或
while ((temp & flag) == 0) {
flag = flag << 1
}
//对nums进行分组
for num in nums {
if flag & num == 0 {
lostNum1 = lostNum1 ^ num
} else {
lostNum2 = lostNum2 ^ num
}
}
return (lostNum1, lostNum2)
}