【LeetCode每日一题】190. 颠倒二进制位

这篇博客介绍了LeetCode的三道编程题,包括190题“颠倒二进制位”,7题“整数反转”和9题“回文数”。对于190题,提供了两种解法,一种是直接模拟,另一种是分组交换法。7题的解法是通过检查反转后是否超出整数范围。9题则判断输入数是否为回文,负数直接返回false,其余情况通过反转比较原数。这些解法都考虑了整数溢出问题。
摘要由CSDN通过智能技术生成

【LeetCode每日一题】190. 颠倒二进制位

  • 190. 颠倒二进制位

  • 7. 整数反转

  • 9. 回文数

今日题目190题,相关题目7、9两道题,一起带进来刷,每日一题微信交流群可以点击右下角:合作转载->联系我,拉你入群。

190. 颠倒二进制位

题目:

颠倒给定的 32 位无符号整数的二进制位。

提示:

请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 -1073741825。

示例 1:

输入: 00000010100101000001111010011100 输出: 00111001011110000010100101000000 解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。

模拟: 直接模拟,对新数进行左移,对每一位取&,拿出当前数,加到新数中,旧数右移。

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t ans = 0;
        for (int i=0;i<32;i++) {
            ans<<=1;
            ans += n&1;
            n>>=1;
        }
        return ans;
    }
};

分组交换法: 类似于归并排序,从32位一半位置进行前后置换,例如1011.....1100...会变成1100...1011....,其中省略部分与前面四位组成16位。随后,再在前半16位与后半16位再进行折半交换,例如:前半16位:11000011 01101110,交换后应该位01101110 11000011,依次类推,直到只剩下1位,要取出交换位的数,需要进行mask,例如:前半16位与中前8位与后8位交换,mask为ff00,32位便是ff00ff00表示32位数中每16位进行mask,右移8位,交换即可。

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        n = (n >> 16) | (n << 16); //低16位与高16位交换
        n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8); // 每16位中低8位和高8位交换
        n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4); // 每8位中低4位和高4位交换
        n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2); // 每4位中低2位和高2位交换 100 = c 0011=3
        n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1); // 每2位中低1位和高1位交换 1010 = a 0101=5
        return n;
    }
};

7. 整数反转

题目:

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−2^31,  2^31 − 1] ,就返回 0。假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:

输入:x = 123 输出:321

示例 2:

输入:x = -123 输出:-321

题解:

直接采用long强制转换与int数进行比较,判断是否越界。

class Solution {
public:
    int reverse(int x) {
        long n = 0;
        while (x) {
            n = n*10+x%10;
            x/=10;
        }
        return (int)n==n ? int(n) : 0;
    }
};

int范围[-2^31,2^31-1],即[-2147483648,2147483647]。

在计算过程中,根据公式:n = n*10+yu,如果n>214748364 或者 n=214748364并且余数大于7,返回0;同样对于负数,如果n<-214748364 或者 n=-214748364并且余数小于8,返回0.

class Solution {
public:
    int reverse(int x) {
        int n = 0;
        while (x) {
            int yu = x%10;
            if (n > 214748364 || (n == 214748364 && yu > 7)) return 0;
            if (n < -214748364 || (n == -214748364 && yu < -8)) return 0;
            n = n*10 + yu;
            x/=10;
        }
        return n;
    }
};

或者不用判断余数,直接判断n。

class Solution {
public:
    int reverse(int x) {
        int n = 0;
        while (x) {
            if (n > 214748364 || n<-214748364) return 0;
            int yu = x%10;
            n = n*10 + yu;
            x/=10;
        }
        return n;
    }
};

9. 回文数

题目:

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。

示例 1:

输入:x = 121 输出:true 示例 2:

输入:x = -121 输出:false 解释:从左向右读, 为 -121 。从右向左读, 为 121- 。因此它不是一个回文数。

题解:

如果是回文数,那么不会溢出,负数直接返回false,其他的便是上述题目解法,比较上述题的结果与原始值即可。

class Solution {
public:
    bool isPalindrome(int x) {
        if (x<0) return false;
        long n = 0;
        int raw_x = x;
        while (x) {
            n = n*10+x%10;
            x/=10;
        }
        int y = ((int)n==n ? int(n) : 0);
        return raw_x == y;
    }
};

本节完~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值