位运算 Leetcode 面试题与简单题

leetcode268. 丢失的数字

https://leetcode-cn.com/problems/missing-number/
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。

解法一:数学法,计算0到n的和,然后减去数组中的值。当值为0,则缺失数字为n,当值不为0,就是其结果
解法二:位运算中的异或。不是要找缺失的数字吗
012345
01245 
由于异或相同为0,不同为1。来两次就可以找到不同的值
public int missingNumber(int[] nums) {
        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            res ^= nums[i];
            res ^= i;
        }
        return res^nums.length;
}

leetcode1720. 解码异或后的数组

https://leetcode-cn.com/problems/decode-xored-array/

未知 整数数组 arr 由 n 个非负整数组成。
经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] = arr[i] XOR arr[i + 1] 。例如,arr = [1,0,2,1] 经编码后得到 encoded = [1,2,3] 。
给你编码后的数组 encoded 和原数组 arr 的第一个元素 first(arr[0])。
请解码返回原数组 arr 。可以证明答案存在并且是唯一的。

解法:由于题目由异或得来,再异或回去一把就是原值
public int[] decode(int[] encoded, int first) {
        int[] arr = new int[encoded.length+1];
        arr[0] = first;
        int len = encoded.length;
        for(int i = 0; i<len; i++){
            arr[i+1] = arr[i] ^ encoded[i];
      }
     
         return arr;
}

leetcode405. 数字转换为十六进制数

** https://leetcode-cn.com/problems/convert-a-number-to-hexadecimal/
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。

解法:这题限制用api去解决问题,咱们只能手动来模拟
15与数字与得末尾,无符号右移4位,相当于除以16public String toHex(int num) {
        char[] s = "0123456789abcdef".toCharArray(); //字符串转数组
        if(num == 0) return "0";
        StringBuffer buffer = new StringBuffer();
        while(num != 0) {
           buffer.append(s[num & 15]);
           num = num >>> 4; //无符号右移
        }
        return buffer.reverse().toString();
  }

leetcode231. 2的幂

https://leetcode-cn.com/problems/power-of-two/
给定一个整数,编写一个函数来判断它是否是 2 的幂次方。

解法:负数和0直接false,当1个数是2的幂次方, 100。。。000,减一为011。。。111.二者相与为0
public boolean isPowerOfTwo(int n) {
        if(n <= 0) return false;
        int t = n & (n-1);
        if(t == 0) return true;
        return false;
}

leetcode 面试题 05.01. 插入

https://leetcode-cn.com/problems/insert-into-bits-lcci/
给定两个整型数字 N 与 M,以及表示比特位置的 i 与 j(i <= j,且从 0 位开始计算)。
编写一种方法,使 M 对应的二进制数字插入 N 对应的二进制数字的第 i ~ j 位区域,不足之处用 0 补齐。

解法:题目意思很简单,就是将中间的一块换成给定的数字
1:让i,j之间的二进制为0001111000
2:取反得到i,j之外的二进制数,中间i,j为0,其余为1110000111
3:与数字n相与得.。。。0000。。。
4 :与m左移i位或运算得答案。。。xxxxx。。。
public static  int insertBits(int N, int M, int i, int j) {
        int t = 0;
        for (int k = i; k <= j; k++) {
            t = t |(1 << k);
        }
        t = ~t;
        t = t & N;
        t = t |(M << i);
        return t;
    }

leetcode371. 两整数之和

https://leetcode-cn.com/problems/sum-of-two-integers/
不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。

解法:a^b异或其实是无进位累加的和 a^b +(a&b) << 1
1.两个整数a, b; a ^ b是无进位的相加;
2.a&b得到每一位的进位,然后左移13.让无进位相加的结果与进位不断的异或,直到进位为0public int getSum(int a, int b) {
        int t, c;
        while(b != 0){
            t = a ^ b;
            c = (a & b) << 1;
            a = t;
            b = c;
        }
        return a;
    }

leetcode136. 只出现一次的数字

https://leetcode-cn.com/problems/single-number/
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

解法:由于异或的特性,相同为0,不同为1,所有找单个,异或解决。
 public int singleNumber(int[] nums) {
        int res = 0;
        for(int i = 0; i< nums.length; i++){
            res ^= nums[i];
        }
        return res;
    }

l

leetcode 位1的个数

https://leetcode-cn.com/problems/number-of-1-bits/
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数

解法:其实就是跟所在的1进行与运算,当不为0,则当前位为11左移i位得到i的位数为1
public int hammingWeight(int n) {
        int count = 0;
        int t, k = 1;
        for (int i = 0; i < 32; i++) {
            t = n & k;
            if(t != 0) count++;
            k <<= 1;
        }
        return count;
}

leetcode 二进制手表

https://leetcode-cn.com/problems/binary-watch/

解法一:回溯加剪枝
解法二:直接暴力破解,用bitCount来统计1的个数即灯的个数。
public List<String> readBinaryWatch(int num) {
        int count = 0;
        List<String> list = new ArrayList<>();
        if(num > 8) return list;
        for (int i = 0; i < 12; i++) {
            count = Integer.bitCount(i);
            for (int j = 0; j < 60; j++) {
                if (count+Integer.bitCount(j) == num) {
                    list.add(String.format("%d:%02d",i,j));;
                }
            }
        }
        return list;
    }

leetcode169. 多数元素

https://leetcode-cn.com/problems/majority-element/
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。

解法:同归于尽
先当前的count是否为0,如果为0,将当前值当结果值用,count置1,不为0,相等加1,不等减一,最后得结果值
public int majorityElement(int[] nums) {
        int count = 0;
        int k = 0;
        for (int i = 0; i < nums.length; i++) {
            if(count == 0) {
                k = nums[i];
                count = 1;
            }else {
               if (k == nums[i]) count++;
               else count--;
            }
        }
        return k;
    }

leetcode面试题 05.07. 配对交换

https://leetcode-cn.com/problems/exchange-lcci/
配对交换。编写程序,交换某个整数的奇数位和偶数位,尽量使用较少的指令(也就是说,位0与位1交换,位2与位3交换,以此类推)。

解法:位运算,&运算取得奇数位,偶数位, 然后奇数位左移1位进行|运算,偶数位右移1位进行|运算
public static int exchangeBits(int num) {
        int res = 0;
        for (int i = 0; i < 30; i+=2) {
            int x = num & (1 << i);
            int y = num & (1 << (i+1));
            res |= (x << 1);
            res |= (y >> 1);
        }
        return res;
    }

leetcode 面试题 16.07. 最大数值

https://leetcode-cn.com/problems/maximum-lcci/
编写一个方法,找出两个数字a和b中最大的那一个。不得使用if-else或其他比较运算符。

解法:不能用比较值,那我就用(a+b+Math.abs(a-b))/2,不过a+b或者a-b会溢出,加一个
 public int maximum(int a, int b) {
        long t = (((long)a+b)+Math.abs(((long)a-b)))/2;
        return (int)t;
    }

位运算,用于交换a,b的值

a = a ^ b;
b = a ^ b;
a = a ^ b;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值