我是靠谱客的博主 虚拟蜡烛,最近开发中收集的这篇文章主要介绍LeetCode进制转换LeetCode 504. 七进制数LeetCode 405. 数字转换为十六进制数Reference,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • LeetCode 504. 七进制数
    • 题目
    • 倒推+迭代
  • LeetCode 405. 数字转换为十六进制数
    • 题目
    • 方法一:位运算 + 分组换算
    • 方法二:倒推 + 迭代
  • Reference


LeetCode 504. 七进制数

题目

  • 504. 七进制数

在这里插入图片描述

倒推+迭代

一个整数的七进制可表示为 n u m 7 : a 0 a 1 … a n − 1 ‾ num_{7}:overline{a_{0}a_{1}dots a_{n-1}} num7:a0a1an1,其中其中 n n n 为其七进制表示的位数, a 0 a_0 a0 为最高位, a n − 1 a_{n-1} an1 为最低位

其对应的十进制表示为:$num_{10}=sum_{i=0}^{n-1}a_{i}times 7^{n-1-i} $。

当要计算一个十进制数对应的七进制表示时,可以先计算最低位 a n − 1 = num 10   m o d   7 a_{n-1} = textit{num}_{10} bmod 7 an1=num10mod7因为 num 10 textit{num}_{10} num10中对 7 有余的部分仅由 a n − 1 a_{n-1} an1 贡献。

从两边都减去最低位 a n − 1 a_{n-1} an1可得:
n u m 10 − a n − 1 = ∑ i = 0 n − 2 a i × 7 n − 1 − i num_{10}-a_{n-1}=sum_{i=0}^{n-2}a_{i} times 7^{n - 1 - i} num10an1=i=0n2ai×7n1i
两边都除以7,可得:
n u m 10 − a n − 1 7 = ∑ i = 0 n − 2 a i × 7 n − 2 − i frac{num_{10}-a_{n-1}}{7}=sum_{i=0}^{n-2}a_{i} times 7^{n - 2 - i} 7num10an1=i=0n2ai×7n2i
此时, n u m 10 − a n − 1 7 frac{num_{10}-a_{n-1}}{7} 7num10an1中对7有余的部分仅由 a n − 2 a_{n-2} an2贡献,可得:
a n − 2 = n u m 10 − a n − 1 7   m o d   7 a_{n-2} =frac{num_{10}-a_{n-1}}{7} bmod 7 an2=7num10an1mod7
不停迭代,可以从最低位到最高位还原出 num 7 textit{num}_7 num7 的各位数字,直到 num 10 textit{num}_{10} num10 归 0。

当输入为负时,可以先取 num textit{num} num 的绝对值来求七进制,最后再添加负号。

class Solution {
    public String convertToBase7(int num) {
        if (num == 0) {
            return "0";
        }
        boolean negative = num < 0;
        num = Math.abs(num);
        StringBuffer digits = new StringBuffer();
        while (num > 0) {
            digits.append(num % 7);
            num /= 7;
        }
        if (negative) {
            digits.append('-');
        }
        return digits.reverse().toString();
    }
}
  • 时间复杂度: O ( log ⁡ ∣ num ∣ ) O(log |textit{num}|) O(lognum),其中 ∣ num ∣ |textit{num}| num 表示 num textit{num} num 的绝对值。循环中最多做 log ⁡ ∣ num ∣ log |textit{num}| lognum 次除法。

  • 空间复杂度: O ( log ⁡ ∣ num ∣ ) O(log |textit{num}|) O(lognum)。字符数组的长度最多为 log ⁡ ∣ num ∣ log |textit{num}| lognum

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

题目

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

在这里插入图片描述

在这里插入图片描述

方法一:位运算 + 分组换算

在补码运算中,最高位表示符号位,符号位是 0 表示正整数和零,符号位是 1 表示负整数。32 位有符号整数的二进制数有 32 位,由于一位十六进制数对应四位二进制数,因此 32 位有符号整数的十六进制数有 8 位。将 num textit{num} num 的二进制数按照四位一组分成 8 组,依次将每一组转换为对应的十六进制数,即可得到 num textit{num} num 的十六进制数。

实现一:

class Solution {
    public String toHex(int num) {
        if (num == 0) {
            return "0";
        }
        char[] chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        StringBuilder res = new StringBuilder();
        while (num != 0) {
            // num 的二进制数按照四位一组分组,依次将每一组转换为对应的十六进制数
            res.append(chars[num & 0xf]);
            // 无符号右移
            num >>>= 4;
        }
        return res.reverse().toString();
    }
}

实现二:

class Solution {
    public String toHex(int num) {
        if (num == 0) return "0";
        StringBuilder sb = new StringBuilder();
        while (num != 0) {
            int u = num & 15;
            char c = (char)(u + '0');
            if (u >= 10) c = (char)(u - 10 + 'a');
            sb.append(c);
            num >>>= 4;
        }
        return sb.reverse().toString();
    }
}

Java中:

>>:带符号右移。正数右移高位补0,负数右移高位补1

>>>:无符号右移。无论是正数还是负数,高位通通补0

实现三:

class Solution {
    public String toHex(int num) {
        if (num == 0) {
            return "0";
        }
        StringBuffer sb = new StringBuffer();
        // 从最高4位开始转换
        for (int i = 7; i >= 0; i --) {
            int val = (num >> (4 * i)) & 0xf;
            // 防止前导 0 
            if (sb.length() > 0 || val > 0) {
                char digit = val < 10 ? (char) ('0' + val) : (char) ('a' + val - 10);
                sb.append(digit);
            }
        }
        return sb.toString();
    }
}

方法二:倒推 + 迭代

可以利用通用的进制转换思路来做(例如504. 七进制数),不断循环 num % knum / k 的操作来构造出 k 进制每一位。

但需要处理「补码」问题:对于负数的 n u m num num,需要先在 n u m num num 基础上加上 2 32 2^{32} 232 的偏移量,再进行进制转换。

CSAPP第一章有介绍2’s Comp. -> Unsigned,也就是用Unsigned的大正数表示Signed负数。举个例子,8位int-1表示为0b11111111(T),无符号整数0b11111111(U)表示为 2 8 − 1 2^8 - 1 281,二者在计算机中二进制表示相同,差值为 2 8 2^8 28。因此先在负数的基础上加上 2 8 2^8 28即可转化为一个大正数,二者的二进制表示相同。在这里32位整形则将原始负数num加上 2 32 2^{32} 232先转换成大正数,以无符号整形表示。该无符号整形与原始有符号负数的2进制是一样的

class Solution {
    public String toHex(int _num) {
        if (_num == 0) return "0";
        long num = _num;
        StringBuilder sb = new StringBuilder();
        if(num < 0) num = (long)(Math.pow(2, 32) + num);
        while (num != 0) {
            long u = num % 16;
            char c = (char)(u + '0');
            if (u >= 10) c = (char)(u - 10 + 'a');
            sb.append(c);
            num /= 16;
        }
        return sb.reverse().toString();
    }
}
  • 时间复杂度:复杂度取决于构造的十六进制数的长度,固定为 C = 8 C = 8 C=8。整体复杂度为 O ( C ) O(C) O(C)
  • 空间复杂度:复杂度取决于构造的十六进制数的长度,固定为 C = 8 C = 8 C=8。整体复杂度为 O ( C ) O(C) O(C)

Reference

  • 七进制数

  • 数字转换为十六进制数

  • AC_OIer

  • RUMI

最后

以上就是虚拟蜡烛为你收集整理的LeetCode进制转换LeetCode 504. 七进制数LeetCode 405. 数字转换为十六进制数Reference的全部内容,希望文章能够帮你解决LeetCode进制转换LeetCode 504. 七进制数LeetCode 405. 数字转换为十六进制数Reference所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部