2025-12-13:十六進制和三十六進制轉化。用go語言,給定一個整數 n,先求它的平方並把該值用大寫字母的 16 進製表示(符號位按需處理,數位使用 0–9 與 A–F),再求它的立方並將該值用大寫字母的 36 進製表示(數位使用 0–9 與 A–Z)。

最後將這兩個進制字符串按順序拼接,作為函數的返回結果。

1 <= n <= 1000。

輸入:n = 13。

輸出: "A91P1"。

解釋:

n * n = 13 * 13 = 169。在十六進制中,它轉換為 (10 * 16) + 9 = 169,對應於 "A9"。

n * n * n = 13 * 13 * 13 = 2197。在三十六進制中,它轉換為 (1 * 362) + (25 * 36) + 1 = 2197,對應於 "1P1"。

連接兩個結果得到 "A9" + "1P1" = "A91P1"。

題目來自力扣3602。

分步過程描述

  1. 給定整數 n = 13
    計算它的平方:
    ( n^2 = 13 \times 13 = 169 )

  2. 平方值轉換為十六進制

    • 調用 toRadix(169, 16)
    • 169 除以 16 的商和餘數依次是:
      • 169 ÷ 16 = 10 餘 9
      • 10 ÷ 16 = 0 餘 10
    • 餘數映射到十六進制字符:9 → '9',10 → 'A'
    • 餘數收集的順序是從低位到高位(9, 10),即 "9A",但最後要反轉,所以得到 "A9"。
  3. 計算立方
    ( n^3 = 13 \times 13 \times 13 = 2197 )

  4. 立方值轉換為三十六進制

    • 調用 toRadix(2197, 36)
    • 2197 除以 36 的步驟:
      • 2197 ÷ 36 = 61 餘 1
        • 餘數 1 → '1'
      • 61 ÷ 36 = 1 餘 25
        • 餘數 25 → 'Z'?不對,要檢查字母映射:
          餘數 0–9 → '0'–'9',餘數 10 → 'A',餘數 11 → 'B',…,餘數 25 → 10+15 = 第 16 個字母? 10→A(0), 11→B(1), ..., 25 是 10+15,所以餘數 25 是 10(A)+15 = 第 16 個字母是 P。
          驗證:餘數 10 → 'A',11 → 'B',12 → 'C',…,25 → 'A' + 15 = 'P' ✅
      • 1 ÷ 36 = 0 餘 1
        • 餘數 1 → '1'
    • 從低位到高位餘數為 1, 25, 1,反轉後是 1, 25, 1 → 字符 '1', 'P', '1' → 字符串 "1P1"。
  5. 拼接結果

    • 十六進制部分 "A9" + 三十六進制部分 "1P1" → "A91P1"

複雜度分析

假設 ( n ) 給定,平方和立方計算是 ( O(1) )。

  • 進制轉換時,循環次數取決於數字在相應進制下的位數,最壞情況出現在 ( n = 1000 ):
    • 平方最大是 ( 10^6 ),十六進制下約 5 位。
    • 立方最大是 ( 10^9 ),三十六進制下約 6 位。
    • 每次循環是常數時間操作。

時間複雜度
每次轉換的位數是 ( O(\log M) ),這裏 M 是 ( n^2 ) 或 ( n^3 )。由於輸入 n ≤ 1000,位數不超過常數範圍,所以可視為 ( O(1) )。但通常按大 O 表示法,是 ( O(\log n) )。

空間複雜度
主要是 strings.Builder 存儲的字符串長度,以及反轉時用的 []rune 臨時空間。額外空間與結果字符串長度成線性,結果字符串長度是 ( O(\log n) )。

結論

  • 總時間複雜度:( O(\log n) )(但 n ≤ 1000 時可看作 ( O(1) ))
  • 總額外空間複雜度:( O(\log n) )(存儲轉換結果所需空間)

Go完整代碼如下:

package main

import (
	"fmt"
	"strings"
)

func concatHex36(n int) string {
	h := n * n
	ans := toRadix(h, 16)

	h = n * n * n
	ans += toRadix(h, 36)

	return ans
}

func toRadix(num, radix int) string {
	if num == 0 {
		return "0"
	}

	var builder strings.Builder
	for num > 0 {
		rem := num % radix
		var ch byte
		if rem < 10 {
			ch = byte('0' + rem)
		} else {
			ch = byte('A' + rem - 10)
		}
		builder.WriteByte(ch)
		num /= radix
	}

	// 反轉字符串
	runes := []rune(builder.String())
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}

	return string(runes)
}

func main() {
	n := 13
	result := concatHex36(n)
	fmt.Println(result)
}

在這裏插入圖片描述

Python完整代碼如下:

# -*-coding:utf-8-*-

def to_radix(num: int, radix: int) -> str:
    """將十進制整數轉換為指定進制的字符串表示"""
    if num == 0:
        return "0"
    
    digits = []
    while num > 0:
        rem = num % radix
        if rem < 10:
            digits.append(chr(ord('0') + rem))
        else:
            digits.append(chr(ord('A') + rem - 10))
        num //= radix
    
    return ''.join(reversed(digits))

def concat_hex36(n: int) -> str:
    """返回 n^2 的十六進制字符串與 n^3 的三十六進制字符串的拼接"""
    h = n * n
    ans = to_radix(h, 16)
    
    h = n * n * n
    ans += to_radix(h, 36)
    
    return ans

def main():
    n = 13
    result = concat_hex36(n)
    print(result)

if __name__ == "__main__":
    main()

在這裏插入圖片描述

C++完整代碼如下:

#include <iostream>
#include <string>

std::string to_radix_no_reverse(int num, int radix) {
    if (num == 0) return "0";

    // 計算最大可能位數
    int temp = num;
    int digits = 0;
    while (temp > 0) {
        temp /= radix;
        digits++;
    }

    // 從最高位開始構建
    std::string result(digits, '\0');
    for (int i = digits - 1; i >= 0; --i) {
        int rem = num % radix;
        result[i] = (rem < 10) ? ('0' + rem) : ('A' + rem - 10);
        num /= radix;
    }

    return result;
}

int main() {
    int n = 13;
    std::string hex_part = to_radix_no_reverse(n * n, 16);
    std::string base36_part = to_radix_no_reverse(n * n * n, 36);
    std::cout << hex_part + base36_part << std::endl;

    return 0;
}

在這裏插入圖片描述