给定一个整数 num,将其转化为 7 进制,并以字符串形式输出。

 

示例 1:

输入: num = 100
输出: "202"

示例 2:

输入: num = -7
输出: "-10"

 

提示:

  • -107 <= num <= 107
Related Topics
  • 数学

  • 👍 95
  • 👎 0
  • 题解

    理解数字的本质,例如:我说我包里有11个苹果,那么就表明我的包里的苹果和我的手指头一一对应的话,还要多出来一个,这个数量可以写作10进制的“11”,也可以写作16进制的“B”,也可以写作二进制的“1011”,他们都表示这么多苹果的数量。

    那么接下来,入参是10进制的数字num,我们也一样在10进制上操作运算,相对应的每满7进1。那么自然的就需要对面num数字除以7,以及取余相关的操作,而除下来的结果依然还是10进制的数字,所以仍然需要除以7继续转换,直到最后没有了。

    又因为最终结果需要输出为字符串,所以需要字符串存储结果还有拼装

    class Solution {
        public String convertToBase7(int num) {
            if (num==0)return "0";
            String signBit = num < 0? "-":"";
            String numStr = "";
            num = num<0?-num:num;
            while (num != 0){
                numStr = (num % 7) + numStr ;
                num = num/7;
            }
            return signBit + numStr;
        }
    }

    提交了下,好像……有一点点点点慢!

    解答成功:
    执行耗时:9 ms,击败了10.25% 的Java用户
    内存消耗:36.6 MB,击败了8.28% 的Java用户

    其实看也知道了,大量的字符串拼接操作,去看下底层代码就知道了,确实比较费时费事。
    那。既然知道了,何不自己来一遍呢?那么,接下来下面这段代码!

    class Solution {
        public String convertToBase7(int num) {
            if (num==0)return "0";
            int signBit = 1;
            if (num < 0){
                signBit = -1;
            }
            char[] arr = new char[10];
            int index = 9;
            num = num<0?-num:num;
            while (num != 0){
                arr[index] = (char)(48+ (num % 7));
                num = num/7;
                index--;
            }
            int length = 10-index-1;
            if (signBit<0){
                length++;
                arr[index] = '-';
                index--;
            }
            char[] newArr = new char[length];
            System.arraycopy(arr,index+1,newArr,0,length);
            return new String(newArr);
        }
    }

    结果

    解答成功:
    执行耗时:0 ms,击败了100.00% 的Java用户
    内存消耗:35.4 MB,击败了97.19% 的Java用户

    至于为啥arr数组是10位,题目中限定了num的范围 -10⁷ <= num <= 10⁷ ,简单算下就知道应该是150666343的7进制 9位数字,再额外加一位符号位的话就是10位了

    写完题解之后去评论区翻了下,看到java.lang.Integer#toString(int, int)这个方法,去看了下源码,好像基本一毛一样

    源码

    public static String toString(int i, int radix) {
            if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
                radix = 10;
    
            /* Use the faster version */
            if (radix == 10) {
                return toString(i);
            }
    
            char buf[] = new char[33];
            boolean negative = (i < 0);
            int charPos = 32;
    
            if (!negative) {
                i = -i;
            }
    
            while (i <= -radix) {
                buf[charPos--] = digits[-(i % radix)];
                i = i / radix;
            }
            buf[charPos] = digits[-i];
    
            if (negative) {
                buf[--charPos] = '-';
            }
    
            return new String(buf, charPos, (33 - charPos));
        }

    这里最后返回的new String的构造方法如下

    public String(char value[], int offset, int count) {
            if (offset < 0) {
                throw new StringIndexOutOfBoundsException(offset);
            }
            if (count <= 0) {
                if (count < 0) {
                    throw new StringIndexOutOfBoundsException(count);
                }
                if (offset <= value.length) {
                    this.value = "".value;
                    return;
                }
            }
            // Note: offset or count might be near -1>>>1.
            if (offset > value.length - count) {
                throw new StringIndexOutOfBoundsException(offset + count);
            }
            this.value = Arrays.copyOfRange(value, offset, offset+count);
        }

    而最终的Arrays.copyOfRange方法内容

    public static char[] copyOfRange(char[] original, int from, int to) {
    int newLength = to - from;
    if (newLength < 0)
    throw new IllegalArgumentException(from + " > " + to);
    char[] copy = new char[newLength];
    System.arraycopy(original, from, copy, 0,
    Math.min(original.length - from, newLength));
    return copy;
    }

    一样的也是用System.arraycopy把有效位的字符复制到一个新的数组中去了

    可把我牛逼坏了,让我叉会儿腰。以上3段代码均出自JDK1.8源码