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。
分步過程描述
-
給定整數 n = 13
計算它的平方:
( n^2 = 13 \times 13 = 169 ) -
平方值轉換為十六進制
- 調用
toRadix(169, 16) - 169 除以 16 的商和餘數依次是:
- 169 ÷ 16 = 10 餘 9
- 10 ÷ 16 = 0 餘 10
- 餘數映射到十六進制字符:9 → '9',10 → 'A'
- 餘數收集的順序是從低位到高位(9, 10),即 "9A",但最後要反轉,所以得到 "A9"。
- 調用
-
計算立方
( n^3 = 13 \times 13 \times 13 = 2197 ) -
立方值轉換為三十六進制
- 調用
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' ✅
- 餘數 25 → 'Z'?不對,要檢查字母映射:
- 1 ÷ 36 = 0 餘 1
- 餘數 1 → '1'
- 2197 ÷ 36 = 61 餘 1
- 從低位到高位餘數為 1, 25, 1,反轉後是 1, 25, 1 → 字符 '1', 'P', '1' → 字符串 "1P1"。
- 調用
-
拼接結果
- 十六進制部分 "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;
}