nc112. 进制转换
题意
给你一个十进制数,求他的
进制数对应的字符串。
1. 递归做法
首先看一下进制的定义:N进制就是逢N进一。
任何一个N进制数M都可以表示为如下形式:
其中,就是
, 求出a0之后,我们可以继续对上式变形:
再套用上面的逻辑,对左边的数再对N取模即可得到. 以此类推可以设计递归解法,设原问题为f(M, N), 则有:
, 其中=M % N.
class Solution {
public:
    string F(int M, int N, int dep = 1) {
        // 本题数据略弱,没有考虑M为0的情况,如果不加辅助参数depth也能AC
        // 但是这里要特判一下,如果是第一层传进来就为0,那要返回0
        // 如果是递归过程中遇到了终点,要返回空字符串,否则答案中会出现前导0
        if (!M) return dep == 1 ? "0" : "";
        // 负数转化为正数
        if (M < 0) return "-" + F(-M, N);
        int a0 = M % N;
        string s0 = to_string(a0);
        if (a0 > 10) {
            s0 = 'A' + a0 - 10;
        }
        return F((M - a0) / N, N, dep+1) + s0;
    }
    string solve(int M, int N) {
        return F(M, N); // 默认为第一层,据上述公式实现
    }
};- 时间复杂度:, 因为每次不断把M除以N,总的复杂度是对数级别。 
- 空间复杂度:, 算法递归 次,每次常数级别空间。 
2. 非递归做法
非递归做法就是模拟我们小学奥数课的手算方法:(以4567转16进制为例,实际上也是上面的数学公式不断迭代求N的幂的系数的过程):
 
因此,
用代码模拟上述过程即可。
class Solution {
public:
    /**
     * 进制转换
     * @param M int整型 给定整数
     * @param N int整型 转换到的进制
     * @return string字符串
     */
    string solve(int M, int N) {
        // 特判,本题没有的数据,但是要更加严谨
        if (!M) return "0";
        // 负数转化为正数
        if (M < 0) return "-" + solve(-M, N);
        string res;
        // 迭代出口为M=0
        while(M) {
            int a = M%N; // 求余数
            string s = to_string(a);
            if (a > 10) {
                s = 'A' + a - 10;
            }
            // 向前拼接
            res = s + res;
            // 求商,进行下一轮迭代
            M /= N;
        }
        return res;
    }
};- 时间复杂度:, 因为每次不断把M除以N,总的复杂度是对数级别。 
- 空间复杂度:, 变量res的长度是M的对数级别。 

 京公网安备 11010502036488号
京公网安备 11010502036488号