汉明距离

  趁着今日还有点时间,记下这道有趣的题,大家觉得有启发请给我点个赞,你们的鼓励是我坚持下去的动力。

  今天的题链接:https://leetcode-cn.com/problems/hamming-distance/

  先贴上题目(属于lettcode上热题Hot100):

   

解法一:(我的解法)

思路:第一步:将两个十进制数转换为二进制数的字符串,其中使用栈和除k商余法。

           第二步:获取各自的长度,得到最长的二进制长度(忽略二进制中前面的零)

           第三步:从二进制字符串的最右边开始遍历,若字符不相同将计数器+1,其中判断较短的二进制字符串遍历完成的情况。

           第四步:返回计数器,即最终的结果。

代码:

        //函数返回值
        int result = 0;
        //两个十进制化为二进制最长的位数
        int maxDigits = 0;
        //得到二进制字符串
        String xS = getBinary(x);
        String yS = getBinary(y);
        //得到二进制的长度
        int xDigits = xS.length();
        int yDigits = yS.length();
        //得到最长的二进制位数
        maxDigits = xDigits > yDigits ? xDigits : yDigits;
        //遍历最长二进制位数的次数,不需要填0,但代码可读性下降
        for (int i = 0; i < maxDigits; i++) {
            //存在遍历完成的数
            if (xDigits <= 0 || yDigits <= 0) {
                //判断是否相等,不相等结果+1
                if (xDigits <= 0 && yS.charAt(yDigits - 1) == '1')
                    result++;
                if (yDigits <= 0 && xS.charAt(xDigits - 1) == '1')
                    result++;
            } else {
                //若都未遍历完,判断位数的值是否相等
                if (xS.charAt(xDigits - 1) != yS.charAt(yDigits - 1)) {
                    result++;
                }
            }
            xDigits--;
            yDigits--;
        }
        return result;
/**************************************************************************/
     //除2商余法---用栈
    public static String getBinary(int x) {
        StringBuilder stringBuilder = new StringBuilder();
        Stack stack = new Stack<>();
        while (x != 0) {
            int mod = x % 2;
            stack.push(mod);
            x = x / 2;
        }
        while (!stack.isEmpty()) {
            stringBuilder.append(stack.pop());
        }
        return stringBuilder.toString();
    }

解法二:(和解法一稍微不同)

根据最长的二进制长度将较短的二进制字符串前面补充0,再分别比较两个二进制字符串的各位是否相等。

主要代码:

        //两数二进制位的差值(不计前面的零)
        int difValue = Math.abs(xDigits - yDigits);
        char needZero = '0';
        //为不够最长位数的字符串数字补零,复杂度部分源于添加0的过程
        if (xDigits > yDigits) {
            while (difValue > 0) {
                yS = needZero + yS;
                difValue--;
            }
        } else {
            while (difValue > 0) {
                xS = needZero + xS;
                difValue--;
            }
        }
        //一一遍历对应,不同result+1
        for (int i = 0; i < maxDigits; i++) {
            if (xS.charAt(i) != yS.charAt(i)) {
                result++;
            }
        }

解法三:(利用异或运算和与运算)

        /**无敌算法:先算亦或(相同为0,不同为1,即n中1的个数为所求答案)
         * 若n不为0,必有一个1,再讲n与n-1做且操作,消除最后的1,
         * 循环过后,消除所有的1,即循环次数为原始n中1的个数
         * */
        //亦或
        int n = x ^ y;
        //若n为0,返回count为0,同时定义和初始化计数器count
        int count = 0;
        //循环n与n-1的与操作,完成1的统计
        while (n != 0) {
            count++;
            n = n & (n - 1);
        }
        return count;

效率上:解法三>>解法一>解法二(解法一不需要额外补零,省去大量字符串连接操作)

解法三真香,空间复杂度为o(1)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值