Bit Manipulation
Bit Manipulation(位运算):
一共五种运算:与,或,异或,左移,右移。
常用技巧:
(1) n & (n-1)能够消灭n中最低位中的1。
(2) 右移:除以2, 左移:乘以2。
(3) 异或性质:交换律,0^a=a, a^a=0;
(3) 将常用字符、数字等均转为按位运算,可以节约空间。
例题
Number of 1 Bits
使用右移。
使用n&(n-1)可以消灭一个1的性质来求解。
1 | public static int hammingWeight(int n) { |
Missing Number
这道题给我们n个数字,是0到n之间的数但是有一个数字去掉了,让我们寻找这个数字,要求线性的时间复杂度和常数级的空间复杂度。
解法一:最直观的一个方法是用等差数列的求和公式求出0到n之间所有的数字之和,然后再遍历数组算出给定数字的累积和,然后做减法,差值就是丢失的那个数字
1 | public static int missingNumber(int[] nums) { |
解法二:,使用位操作Bit Manipulation来解的,用到了异或操作的特性。思路是既然0到n之间少了一个数,我们将这个少了一个数的数组合0到n之间完整的数组异或一下,那么相同的数字都变为0了,剩下的就是少了的那个数字了
1 | public static int missingNumber1(int[] nums) { |
解法三:这道题还可以用二分查找法来做,我们首先要对数组排序,然后我们用二分查找法算出中间元素的下标,然后用元素值和下标值之间做对比,如果元素值大于下标值,则说明缺失的数字在左边,作为读者的你可能会提出,排序的时间复杂度都不止O(n),何必要多此一举用二分查找,还不如用上面两种方法呢。对,你说的没错,但是在面试的时候,有可能人家给你的数组就是排好序的,那么此时用二分查找法肯定要优于上面两种方法,所以这种方法最好也要掌握以下
1 | public static int missingNumber2(int[] nums) { |
Power of Two
使用n&(n-1)=0来判断。
注意0和负数的情况。
这道题让我们判断一个数是否为2的次方数,而且要求时间和空间复杂度都为常数
解法一:那么我们很容易看出来2的次方数都只有一个1,剩下的都是0,所以我们的解题思路就有了,我们只要每次判断最低位是否为1,然后向右移位,最后统计1的个数即可判断是否是2的次方数
1 | public static boolean isPowerOfTwo(int n) { |
解法二:这道题还有一个技巧,如果一个数是2的次方数的话,根据上面分析,那么它的二进数必然是最高位为1,其它都为0,那么如果此时我们减1的话,则最高位会降一位,其余为0的位现在都为变为1,那么我们把两数相与,就会得到0,用这个性质也能来解题。
1 | public static boolean isPowerOfTwo2(int n){ |