leetcode 1611

1611:使整数变为0的最少操作次数

我们需要确定在0 ≤ n ≤ 10⁹的范围内,整数n转换为二进制后最多有多少位。

二进制位数的基本概念

一个正整数n的二进制表示的位数可以通过以下公式计算:

位数=⌊log2​n⌋+1

这个公式的含义是:n的二进制位数比n的二对数(向下取整)多1。这是因为:

  • 如果n是2的幂次方(例如1, 2, 4, 8, ...),那么log₂n是整数,位数就是log₂n + 1。

  • 如果n不是2的幂次方,那么log₂n不是整数,向下取整后加1得到位数。

计算10⁹的二进制位数

我们需要找到最大的n在范围内,即n = 10⁹。计算其二进制位数:

位数=⌊log2​109⌋+1

首先计算log₂10⁹:

log2​109=9×log2​10

我们知道:

log2​10≈3.321928

因此:

9×log2​10≈9×3.321928≈29.897352

然后取 floor:

⌊29.897352⌋=29

最后加1:

29+1=30

因此,10⁹的二进制表示有30位(数目),对应下标0...29。

复制代码
        while(n) {
            int id1 = -1, id2 = -1;
            for(int i = 30; i >= 0; i--) { // 从高位开始遍历,寻找 1
                if((1 << i) & n) {
                    if(id1 == -1) id1 = i; // 记录较高位的 1
                    else if(id2 == -1) id2 = i; // 记录较低位的 1
                    else {
                        break; // 都找到了就 break
                    }
                }
            }

这段代码的目的是:n 的二进制表示中,从高位到低位,找到最高的两个 1 的位置,分别记为 id1id2

复制代码
(1 << i) & n

作用判断 n 的第 i 位是否为 1

  • & n:++与 n 按位与,如果结果非零,说明 n 的第 i 位是 1。++

  • 按位与就是"两个数的二进制对齐,逐位做逻辑与",结果只有对应位同时是 1 的位置才是 1

    n^=(1<<id1);

复制代码
class Solution {
public:
    int minimumOneBitOperations(int n) {
        int cnt[30];  //10⁹的二进制表示有30位(数目),对应下标0...29
        int res=0;
        for(int i=0;i<30;i++) cnt[i]=(1<<(i+1))-1;  //将规律 1 的结果预处理出来存在数组 cnt[i] = 2^(i+1) - 1
        while(n){
            int id1=-1,id2=-1;
            for(int i=29;i>=0;i--){  //从高位开始遍历,寻找 1
                if((1<<i)&n){  //判断 n 的第 i 位是否为 1,按位与(包括第0位)
                    if(id1==-1) id1=i;  //记录较高位的 1
                    else if(id2==-1) id2=i;   //记录较低位的 1
                    else{
                        break;  //都找到了就 break
                    }
                }
            }
            if(id2==-1){  //只找到一个
                n^=(1<<id1);  //第 id1 位被反转,其余位保持不变
                res+=cnt[id1];  //规律1
            }
            else{
                n^=(1<<id1);
                n^=(1<<id2);
                res+=(cnt[id1]-cnt[id2]); //规律2
            }
        }

        return res;
    }
};
相关推荐
CQ_YM1 天前
数据结构之队列
c语言·数据结构·算法·
VekiSon1 天前
数据结构与算法——树和哈希表
数据结构·算法
大江东去浪淘尽千古风流人物1 天前
【DSP】向量化操作的误差来源分析及其经典解决方案
linux·运维·人工智能·算法·vr·dsp开发·mr
Unstoppable221 天前
代码随想录算法训练营第 56 天 | 拓扑排序精讲、Dijkstra(朴素版)精讲
java·数据结构·算法·
饕餮怪程序猿1 天前
A*算法(C++实现)
开发语言·c++·算法
电饭叔1 天前
不含Luhn算法《python语言程序设计》2018版--第8章14题利用字符串输入作为一个信用卡号之二(识别卡号有效)
java·python·算法
2301_800256111 天前
8.2 空间查询基本组件 核心知识点总结
数据库·人工智能·算法
不穿格子的程序员1 天前
从零开始写算法——矩阵类题:矩阵置零 + 螺旋矩阵
线性代数·算法·矩阵
资深web全栈开发1 天前
LeetCode 3432. 统计元素和差值为偶数的分区方案数
算法·leetcode
黎茗Dawn1 天前
DDPM-KL 散度与 L2 损失
人工智能·算法·机器学习