力扣面试题 26 - 翻转数位

题目:

给定一个32位整数 num,你可以将一个数位从0变为1。请编写一个程序,找出你能够获得的最长的一串1的长度。

示例 1:

输入: num= 1775(11011101111)输出: 8

示例 2:

输入: num= 7(0111)输出: 4

思路:

  • 二进制表示与位操作
    需要将给定的整数 num 转换成二进制形式,并对其逐位进行操作。C语言中可以通过位运算(如按位与&、或|、移位>>)来操作整数的每一位。

  • 分段处理连续的 1
    首先,分析 num 中哪些部分连续包含 1,可以通过逐位扫描来实现。记录每一段连续的 1 的长度。

  • 插入一个 0 并连接段
    每次遇到一个 0 时,考虑将其变为 1,并将其两边的连续 1 段合并。如果连续 1 的段之间有一个 0 的间隔,合并后的长度为两段长度之和加 1。

  • 动态更新最长长度
    遍历整个二进制位的过程中,维护一个变量用于记录最大连续 1 的长度,实时更新。

  • 特例处理
    如果输入是负数(有符号整数的情况),需要特别注意其二进制补码表示。否则,如果输入本身已经是全 1 的情况,也需要特殊处理(无需修改即可输出结果)。

C代码:

int reverseBits(int num) {
    if (num == 0){
        return 1;
    }
    if (num == -1) {
        // 如果所有位都是 1,直接返回 32 位长度
        return 32;
    }

    // 分段统计,记录连续 1 的长度
    int max_length = 0;
    int current_length = 0;  // 当前段连续 1 的长度
    int previous_length = 0; // 前一段连续 1 的长度

    for (int i = 0; i < 32; i++) {
        if (num & 1) {
            // 当前位是 1,增加当前段长度
            current_length++;
        } else {
            // 当前位是 0,尝试翻转并合并两段连续 1
            previous_length = current_length;
            current_length = 0;
        }

        // 更新最大长度,考虑翻转后连接的可能
        max_length = (previous_length + current_length + 1 > max_length)
                         ? (previous_length + current_length + 1)
                         : max_length;

        // 右移检查下一位
        num >>= 1;
    }

    return max_length;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值