LeetCode.405 数字转换为十六进制数

149 阅读2分钟

这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

题目描述:

405. 数字转换为十六进制数 - 力扣(LeetCode) (leetcode-cn.com)

给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。

注意:

  1. 十六进制中所有字母(a-f)都必须是小写。
  2. 十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。 
  3. 给定的数确保在32位有符号整数范围内。
  4. 不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。

示例一

输入:
26

输出:
"1a"

示例二

输入:
-1

输出:
"ffffffff"

思路分析

模拟

这一题关键在于对计算机存储的相关知识得有所了解。

这里就直接摘抄 大佬 的总结了。

int 型整数存储范围在 [231,2311][-2^{31}, 2^{31} - 1]内,且在计算机内部以补码形式表示,共 32 位,最高位为符号位,负数符号位为 1,正数为 0

所以,在计算机中,[0,2311][0, 2^{31} - 1] 范围内的数对应的十六进制存储方式为 00000000-7fffffff[231,1][-2^{31},-1]范围内的数对应的十六进制存储方式为 80000000-ffffffff

下面就是分情况了,如果是正数,我们之前做过转二进制的,原理大概类似, %16 即可。

如果是负数的话,其补码范围是 当输入数是负数时, 其补码的数字范围就是[0,2311][0,2^{31}-1]

我们需要找一种方法将其转为正数, 且不影响补码间的计算。

这样也可以直接复用正数的迭代方法进行计算。

我们可以把负数加上2322^{32},这样就可以直接进行十六进制的转换了。

AC代码

class Solution {
    fun toHex(num: Int): String {
        val map: List<String> = arrayListOf(
            "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"
        )
        if(num == 0) return "0"
        var i = 7

        var ans = ""
        while (i >= 0){
            val value = (num shr (4 * i)) and 0xf  //  右移后按位与 提取高四位
            if(value > 0 || ans.isNotEmpty()) {
                ans += map[value]
            }
            i --
        }

        return ans
    }
}

总结

需要一点整数存储的知识即可轻松上分。

参考

数字转换为十六进制数 - 数字转换为十六进制数 - 力扣(LeetCode) (leetcode-cn.com)

【算法小爱】国庆2.0(附带技术类文章目录) - 数字转换为十六进制数 - 力扣(LeetCode) (leetcode-cn.com)

kotlin shr & 0xf - 数字转换为十六进制数 - 力扣(LeetCode) (leetcode-cn.com)