6.25 数学简单&中等 461 477 50 693

461 汉明距离

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。
给你两个整数 x 和 y,计算并返回它们之间的汉明距离。

思路:对两个int十进制转二进制的过程中判断,有点像之前做的位1的数目
class Solution {
public:
    int hammingDistance(int x, int y) {    
        int ans = 0;
        while(x>y?x:y){
            if(x%2 != y%2){
                ans++;
            }
            x /= 2;
            y /= 2;
        }
        return ans;
    }
};

这题确实像位1的数目,感觉解题思路都差不多,先异或运算,相同为0,不同为1,最后判断1的个数就好。

class Solution {
public:
    int hammingDistance(int x, int y) {
        //位运算,将两者异或,相同为0 不同为1,然后将得到的二进制找最低位1就行了
        uint32_t n = 0;
        int ans = 0;
        n = x ^ y;
        while(n){
            n &= (n - 1);
            ans++;
        }
        return ans;
    }
};

477 汉明距离总和

两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。
给你一个整数数组 nums,请你计算并返回 nums 中任意两个数之间 汉明距离的总和 。

思路:和汉明距离的计算没啥太大差别,目前来看只是增加了要多组合几次数组中的整数
class Solution {
public:
     int hammingDistance(int x, int y) {
        //位运算,将两者异或,相同为0 不同为1,然后将得到的二进制找最低位1就行了
        uint32_t n = 0;
        int ans = 0;
        n = x ^ y;
        while(n){
            n &= (n - 1);
            ans++;
        }
        return ans;
    }

    int totalHammingDistance(vector<int>& nums) {
        //想多了还需要删除相等的两个整数,人家汉明距离就为0哇
        int len = nums.size();
        int ans = 0;
        for(int i = 0 ; i < len ; i++){
            for(int j = i+1 ; j < len ; j++){
                ans += hammingDistance(nums[i] , nums[j]);
            }
        }
        return ans;
    }
};

但是上面的代码,在数组中的整数很大时以及数组很长时是会出现执行时间超时的报错。原因是因为我遍历了两次数组nums,时间复杂度为 O ( n 2 ) O(n^2) O(n2)
用了chatgpt优化,提供了一个不错的思路,可以将时间复杂度降低为 O ( n ) O(n) O(n): 直接判断nums每个数的32位中第 1 位 第 2 位…第32位为1 or 0,指出有n个1 (len-n)个0,然后n*(len-n)每一位就有这么多的组合,最后循环32次,全部相加就是结果了。

class Solution {
public:
    int totalHammingDistance(vector<int>& nums) {
        int len = nums.size() , ans = 0;
        for(int i = 0 ; i < 32 ; i++){
            int countOne = 0;
            for(int num : nums){
                if((num >> i) & 1){
                    countOne++;
                }    
            }
            ans += countOne * (len - countOne);
        }
        return ans;
    }
};

看了官方题解也是这个思路,有一点,就是他循环了30次,因为题目中的提示nums[i] <= 1 0 9 10^9 109 1 0 9 < 2 30 10^9 < 2^{30} 109<230,可以记一下。
还有就是,如果还碰到中等难度的题,记得多留点心眼,还用暴力求解多少有点确实脑干的美。

Pow(x,n)

How to say…为啥这个也能

class Solution {
public:
    double myPow(double x, int n) {
        //不用暴力求解
        return pow(x,n);
    }
};

693 交替位二进制数

给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。

思路:掩码的话,在这里还是有点子复杂了
class Solution {
public:
    bool hasAlternatingBits(uint32_t n) {
        while(n){
            int f = n & 1;
            if( (n & 1) != ((n >> 1) & 1) ){
                n >>= 1;
            }
            else{
                return false;
            }
        }
        return true;

    }
};
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值