LeetCode41--数字的补数、交替为二进制数、二进制表示中实数个计算置位、二进制链表转整数、将数字变0的操作次数、数组异或操作、解码异或后的数组

这篇博客主要介绍了LeetCode中关于二进制的7个经典问题,包括:计算数字的补数、构造交替位的二进制数、求二进制表示中的实数个计算置位、将二进制链表转换为整数、确定使数字变为0的操作次数、数组的异或操作以及如何解码异或后的数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.数字的补数

//给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。 
// 
//
// 示例 1: 
//
// 输入: 5
//输出: 2
//解释: 5 的二进制表示为 101(没有前导零位),其补数为 010。所以你需要输出 2 。
// 
//
// 示例 2: 
//
// 输入: 1
//输出: 0
//解释: 1 的二进制表示为 1(没有前导零位),其补数为 0。所以你需要输出 0 。
// 
//
// 
//
// 注意: 
//
// 
// 给定的整数保证在 32 位带符号整数的范围内。 
// 你可以假定二进制数不包含前导零位。 
// 本题与 1009 https://leetcode-cn.com/problems/complement-of-base-10-integer/ 相同 
// 
// Related Topics 位运算
public int findComplement(int num) {
        int n = 0;
        int sum = 0;
        while(num != 0){
            int temp = num & 1;
            if(temp == 0){
                sum += Math.pow(2,n);
            }
            num = num >> 1;
            n++;
        }
        return sum;
    }

 2.交替位二进制数

//给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。 
//
// 
//
// 示例 1: 
//
// 
//输入:n = 5
//输出:true
//解释:5 的二进制表示是:101
// 
//
// 示例 2: 
//
// 
//输入:n = 7
//输出:false
//解释:7 的二进制表示是:111. 
//
// 示例 3: 
//
// 
//输入:n = 11
//输出:false
//解释:11 的二进制表示是:1011. 
//
// 示例 4: 
//
// 
//输入:n = 10
//输出:true
//解释:10 的二进制表示是:1010. 
//
// 示例 5: 
//
// 
//输入:n = 3
//输出:false
// 
//
// 
//
// 提示: 
//
// 
// 1 <= n <= 231 - 1 
// 
// Related Topics 位运算
public boolean hasAlternatingBits(int n) {
        while(n != 0){
            int m = n&1;
            int k = (n>>1)&1;
            if(k == m){
                return false;
            }
            n = n >> 1;
        }
        return true;
    }

 3.二进制表示中实数个计算置位

//给定两个整数 L 和 R ,找到闭区间 [L, R] 范围内,计算置位位数为质数的整数个数。 
//
// (注意,计算置位代表二进制表示中1的个数。例如 21 的二进制表示 10101 有 3 个计算置位。还有,1 不是质数。) 
//
// 示例 1: 
//
// 
//输入: L = 6, R = 10
//输出: 4
//解释:
//6 -> 110 (2 个计算置位,2 是质数)
//7 -> 111 (3 个计算置位,3 是质数)
//9 -> 1001 (2 个计算置位,2 是质数)
//10-> 1010 (2 个计算置位,2 是质数)
// 
//
// 示例 2: 
//
// 
//输入: L = 10, R = 15
//输出: 5
//解释:
//10 -> 1010 (2 个计算置位, 2 是质数)
//11 -> 1011 (3 个计算置位, 3 是质数)
//12 -> 1100 (2 个计算置位, 2 是质数)
//13 -> 1101 (3 个计算置位, 3 是质数)
//14 -> 1110 (3 个计算置位, 3 是质数)
//15 -> 1111 (4 个计算置位, 4 不是质数)
// 
//
// 注意: 
//
// 
// L, R 是 L <= R 且在 [1, 10^6] 中的整数。 
// R - L 的最大值为 10000。 
// 
// Related Topics 位运算
public int countPrimeSetBits(int L, int R) {
        int sum = 0;
        for (int i = L; i < R+1; i++) {
            int temp = Integer.bitCount(i);
            if(isPrime(temp)){
                sum++;
            }
        }
        return sum;
    }
    private boolean isPrime(int m){
        if(m == 1){
            return false;
        }
        if(m == 2){
            return true;
        }
        for (int i = 2; i < m; i++) {
            if(m % i == 0){
                return false;
            }
        }
        return true;
    }

 4.二进制链表转整数

//给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 
//
// 请你返回该链表所表示数字的 十进制值 。 
//
// 
//
// 示例 1: 
//
// 
//
// 输入:head = [1,0,1]
//输出:5
//解释:二进制数 (101) 转化为十进制数 (5)
// 
//
// 示例 2: 
//
// 输入:head = [0]
//输出:0
// 
//
// 示例 3: 
//
// 输入:head = [1]
//输出:1
// 
//
// 示例 4: 
//
// 输入:head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0]
//输出:18880
// 
//
// 示例 5: 
//
// 输入:head = [0,0]
//输出:0
// 
//
// 
//
// 提示: 
//
// 
// 链表不为空。 
// 链表的结点总数不超过 30。 
// 每个结点的值不是 0 就是 1。 
// 
// Related Topics 位运算 链表
public int getDecimalValue(ListNode head) {
    	int sum = 0;
		while (head != null){
			if(head.val == 1){
				sum = sum * 2 + 1;
			}else {
				sum = sum * 2;
			}
			head = head.next;
		}
		return sum;
    }

 5.将数字变0的操作次数

//给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。 
//
// 
//
// 示例 1: 
//
// 输入:num = 14
//输出:6
//解释:
//步骤 1) 14 是偶数,除以 2 得到 7 。
//步骤 2) 7 是奇数,减 1 得到 6 。
//步骤 3) 6 是偶数,除以 2 得到 3 。
//步骤 4) 3 是奇数,减 1 得到 2 。
//步骤 5) 2 是偶数,除以 2 得到 1 。
//步骤 6) 1 是奇数,减 1 得到 0 。
// 
//
// 示例 2: 
//
// 输入:num = 8
//输出:4
//解释:
//步骤 1) 8 是偶数,除以 2 得到 4 。
//步骤 2) 4 是偶数,除以 2 得到 2 。
//步骤 3) 2 是偶数,除以 2 得到 1 。
//步骤 4) 1 是奇数,减 1 得到 0 。
// 
//
// 示例 3: 
//
// 输入:num = 123
//输出:12
// 
//
// 
//
// 提示: 
//
// 
// 0 <= num <= 10^6 
// 
// Related Topics 位运算
public int numberOfSteps (int num) {
        int n = 0;
        while(num != 0){
            if(num % 2 == 0){
                num = num /2;
                n++;
            }else{
                num = num - 1;
                n++;
            }
        }
        return n;
    }

 6.数组异或操作

//给你两个整数,n 和 start 。 
//
// 数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。 
//
// 请返回 nums 中所有元素按位异或(XOR)后得到的结果。 
//
// 
//
// 示例 1: 
//
// 输入:n = 5, start = 0
//输出:8
//解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
//     "^" 为按位异或 XOR 运算符。
// 
//
// 示例 2: 
//
// 输入:n = 4, start = 3
//输出:8
//解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8. 
//
// 示例 3: 
//
// 输入:n = 1, start = 7
//输出:7
// 
//
// 示例 4: 
//
// 输入:n = 10, start = 5
//输出:2
// 
//
// 
//
// 提示: 
//
// 
// 1 <= n <= 1000 
// 0 <= start <= 1000 
// n == nums.length 
// 
// Related Topics 位运算 数组
public int xorOperation(int n, int start) {
        int res = start;
        for (int i = 1; i < n; i++) {
            int temp = start + 2*i;
            res ^= temp;
        }
        return res;
    }

 7.解码异或后的数组

//未知 整数数组 arr 由 n 个非负整数组成。 
//
// 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] = arr[i] XOR arr[i + 1] 。例如,a
//rr = [1,0,2,1] 经编码后得到 encoded = [1,2,3] 。 
//
// 给你编码后的数组 encoded 和原数组 arr 的第一个元素 first(arr[0])。 
//
// 请解码返回原数组 arr 。可以证明答案存在并且是唯一的。 
//
// 
//
// 示例 1: 
//
// 
//输入:encoded = [1,2,3], first = 1
//输出:[1,0,2,1]
//解释:若 arr = [1,0,2,1] ,那么 first = 1 且 encoded = [1 XOR 0, 0 XOR 2, 2 XOR 1] = [
//1,2,3]
// 
//
// 示例 2: 
//
// 
//输入:encoded = [6,2,7,3], first = 4
//输出:[4,2,0,7,4]
// 
//
// 
//
// 提示: 
//
// 
// 2 <= n <= 104 
// encoded.length == n - 1 
// 0 <= encoded[i] <= 105 
// 0 <= first <= 105 
// 
// Related Topics 位运算
public int[] decode(int[] encoded, int first) {
        int[] decode = new int[encoded.length+1];
        decode[0] = first;
        for (int i = 1; i < encoded.length+1; i++) {
            decode[i] = encoded[i-1]^decode[i-1];
        }
        return decode;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值