java数据结构与算法刷题-----LeetCode405. 数字转换为十六进制数

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

文章目录

在这里插入图片描述

分组位运算

这道题正常来说可以用转换7进制的思想来,但是题目有特殊要求,负数要求补码形式,就不能用这个思路,只能用位运算了,有兴趣的可以参考

🏆LeetCode504. 七进制数https://blog.csdn.net/grd_java/article/details/137261543
解题思路:时间复杂度O( k k k),空间复杂度O( k k k),k是16进制的二进制组数(4位一组),32位共8组,k=8
  1. 26的二进制(补码)为:0000,0000,0000,0000,0000,0000,0001,1010,对应的组号为7组,6组,5组,4组,3组,2组,1组,0组
  2. 我们都知道8421码是二进制转换为16进制常用的方法,例如二进制1010的8421码为1*8+0*4+1*2+0*1 = 8+0+2+1 = 10 = a
  3. 也就是说,只要我们每次只截取4位单独进行8421转换,就可以完成16进制的转换
  4. 但是如何用计算机实现这个效果呢?我们如何将其按4位为一组截取出来呢?
  1. 16进制最大的值是15也就是0xf。对应二进制为0000,0000,0000,0000,0000,0000,0000,1111
  2. 我们只需要将 任意值 与(&) 0xf就可以只得到最后4位,其余全是0.
  3. 例如26的二进制(补码)为:
    0000,0000,0000,0000,0000,0000,0001,1010,与上&,15这个数0xf,也就是
    0000,0000,0000,0000,0000,0000,0000,1111 =
    0000,0000,0000,0000,0000,0000,0000,1010 = 10.我们发现成功将第0组截取了出来
  4. 然后我们对26右移4位,变成
    0000,0000,0000,0000,0000,0000,0000,0001,与上&,15这个数0xf,也就是
    0000,0000,0000,0000,0000,0000,0000,1111 =
    0000,0000,0000,0000,0000,0000,0000,0001 = 1.我们发现成功将第1组截取了出来

也就是说,想要对应的组数,例如最后一组7组,只需要将0-6组全部右位移走,然后与上0xf即可获取,简单来说就是[7组,6组,5组,4组,3组,2组,1组,0组] 右位移(>>) 6组 = [0,0,0,0,0,0,0,7组],[7组,6组,5组,4组,3组,2组,1组,0组] 右位移(>>) 3组 = [0,0,0,7组,6组,5组,4组,3组],此时与上0fx就会截取最低位的一组

  1. 对应到二进制上,组只是我们对其规划的,实际上需要一个二进制一个二进制的位移。
  2. 例如右移6组,就需要右位移6*4=24位二进制.我们发现如果想要位移0组就位移0*4个二进制,想要位移1组,就位移1*4个二进制,想要第7组就需要右位移6组,就需要位移6*4个二进制位
  3. 因此,我们可以搞一个for循环,循环7次,第一次取第7组,第二次取第6组…
代码

在这里插入图片描述

class Solution {
    static final char[] digits = {
            '0' , '1' , '2' , '3' , '4' , '5' ,
            '6' , '7' , '8' , '9' , 'a' , 'b' ,
            'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
            'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
            'o' , 'p' , 'q' , 'r' , 's' , 't' ,
            'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };//对应表,我们想要用int的0得到char的'0'。而通过这个会有更好的效率,另外如果是16进制,10对应a,11对应b....
    public String toHex(int num) {
        if (num == 0) return "0";//0无需转换
        StringBuffer sb = new StringBuffer();//保存结果
        for (int i = 7; i >= 0; i --) {//从高位开始转换
            int val = (num >> (4 * i)) & 0xf;//依次从高位组到低位组取,先将目标组移到num的最后4位,然后将最后4位取出,就取出了目标组
            if (sb.length() > 0 || val > 0) {//防止前置0的出现,如果sb已经有值,则当前val是0也不会是前置0.而如果sb中没有值,那么当前val这个值进入sb一定是前置0
//                char digit = val < 10 ? (char) ('0' + val) : (char) ('a' + val - 10);//如果val<10,原样输出,如果>10,就是a,b,c,d,e,f
                char digit = digits[val];//但是如果预先处理,直接通过val就可以得到目标数,例如val = 15,会得到f,val = 0,会得到0
                sb.append(digit);//将字符放入
            }
        }
        return sb.toString();
    }
}
  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值