翻转数位题目解释和代码

这段代码的功能是计算一个32位整数中,经过至多一次位翻转(0变1或1变0)后能得到的连续1的最大长度 。例如,输入1775(二进制11011101111),翻转中间的0后变为11011111111,连续1的最大长度为8。

核心思路

代码通过维护两个变量curinsert来跟踪当前连续1的长度和包含一次翻转的最长长度:

  1. cur:记录当前连续1的长度(遇到0时重置为0)。
  2. insert :记录包含一次翻转的连续1的最大长度。每次遇到0时,insert更新为cur + 1(即把当前0翻转后的长度)。
  3. 遍历每一位 :检查每一位是0还是1,并更新curinsert的值,最终取最大值res

代码逐行解释

cpp 复制代码
int reverseBits(int num) {
    int res = 0;    // 最终结果:连续1的最大长度
    int cur = 0;    // 当前连续1的长度
    int insert = 0; // 包含一次翻转的连续1的长度

    for (int i = 0; i < 32; ++i)  // 遍历32位整数的每一位
    {
        if (num & (1 << i))  // 如果当前位是1
        {
            cur++;       // 连续1的长度加1
            insert++;    // 包含翻转的长度也加1
        }
        else  // 如果当前位是0
        {
            insert = cur + 1;  // 翻转当前0,长度为前面连续1的长度+1
            cur = 0;           // 重置当前连续1的长度为0
        }
        res = max(res, insert);  // 更新最大长度
    }

    return res;
}

关键逻辑分析

  1. 遇到1时
    • curinsert都加1,表示连续1的长度增加。
  2. 遇到0时
    • insert更新为cur + 1,即假设翻转当前0后的总长度。
    • cur重置为0,因为当前连续1的序列被打断。
  3. 为什么有效?
    • 每次遇到0时,insert记录了"上一段连续1 + 当前翻转的0"的长度。
    • 如果后续还有连续1,insert会继续累加,相当于"上一段连续1 + 翻转的0 + 新的连续1"。

示例验证

输入num = 1775(二进制11011101111):

复制代码
位: 1 1 0 1 1 1 0 1 1 1 1 0 ...(其余为0)
i   0 1 2 3 4 5 6 7 8 9 10 11...
cur 1 2 0 1 2 3 0 1 2 3 4 0...
ins 1 2 3 1 2 3 4 1 2 3 4 5...
res 1 2 3 3 3 3 4 4 4 4 4 5...

最终res = 8(翻转第6位后的连续长度)

总结

这段代码巧妙地利用一次遍历,通过维护两个变量curinsert,在线性时间内计算出翻转至多一位后的最长连续1的长度。其核心思想是动态更新包含一次翻转的最大长度,确保正确性的同时保持高效性。

相关推荐
凌肖战2 小时前
力扣网C语言编程题:在数组中查找目标值位置之二分查找法
c语言·算法·leetcode
weixin_478689762 小时前
十大排序算法汇总
java·算法·排序算法
luofeiju2 小时前
使用LU分解求解线性方程组
线性代数·算法
学不动CV了3 小时前
数据结构---线性表理解(一)
数据结构
SKYDROID云卓小助手3 小时前
无人设备遥控器之自动调整编码技术篇
人工智能·嵌入式硬件·算法·自动化·信号处理
ysa0510303 小时前
数论基础知识和模板
数据结构·c++·笔记·算法
GEEK零零七3 小时前
Leetcode 1103. 分糖果 II
数学·算法·leetcode·等差数列
今天背单词了吗9804 小时前
算法学习笔记:7.Dijkstra 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·数据结构·笔记·算法
气质、小青年!4 小时前
【排序算法】
c语言·数据结构
重庆小透明5 小时前
力扣刷题记录【1】146.LRU缓存
java·后端·学习·算法·leetcode·缓存