目錄
核心思想:數字的“拆分”與“重組”
分步拆解(以輸入?123?為例)
關鍵操作詳解
為什么能處理中間或末尾的0?
數學本質
總結
題目描述
解題思路
代碼實現
代碼解析
復雜度分析
示例演示
總結
核心思想:數字的“拆分”與“重組”
假設原數字是?123,它的每一位可以表示為:
123 = 1×100 + 2×10 + 3×1
反轉后的數字是?321,即:
321 = 3×100 + 2×10 + 1×1
函數通過循環逐步“拆解”原數字的每一位,再“重組”到結果中。
分步拆解(以輸入?123
?為例)
循環次數 | num | num%10(取末位) | res = res*10 + 末位 | num = parseInt(num/10) |
---|---|---|---|---|
初始值 | 123 | - | 0 | - |
第一次循環 | 123 | 3 | 0×10 + 3 =?3 | 123→12 |
第二次循環 | 12 | 2 | 3×10 + 2 =?32 | 12→1 |
第三次循環 | 1 | 1 | 32×10 + 1 =?321 | 1→0 |
循環結束,返回?res=321
。
關鍵操作詳解
-
取末位(
num % 10
)
%
?是取余操作,比如?123%10=3
,12%10=2
,1%10=1
。
這相當于每次取出?num
?的最后一位數字。 -
重組(
res = res*10 + 末位
)-
res*10
:將當前結果左移一位(騰出個位)。 -
+ 末位
:將新提取的末位填入個位。
比如: -
初始?
res=0
?→ 填入3 →?res=3
-
下次循環?
res=3×10=30
?→ 填入2 →?res=32
-
最后?
res=32×10=320
?→ 填入1 →?res=321
-
-
去掉末位(
num = parseInt(num/10)
)
除以10后取整,相當于去掉最后一位。
例如:123→12
,12→1
,1→0
(循環終止)。
為什么能處理中間或末尾的0?
-
末尾的0(如輸入?
1200
)
第一次循環提取末位0 →?res=0×10+0=0
,num=120
第二次循環提取末位0 →?res=0×10+0=0
,num=12
第三次循環提取2 →?res=0×10+2=2
,num=1
第四次循環提取1 →?res=2×10+1=21
,num=0
最終結果是?21
,末尾的0被自動“舍棄”。 -
中間的0(如輸入?
10203
)
反轉后為?30201
,中間的0會被保留,因為每次循環都會嚴格按順序提取數字。
數學本質
原數字可以表示為:
num = a×10? + b×10??1 + ... + z×10?
反轉后的數字則是:
res = z×10? + ... + b×101 + a×10?
函數通過循環逐步剝離原數字的每一位(從低位到高位),再按反方向重組。
總結
這個算法的精妙之處在于:
-
逐位處理:每次只操作一位數字。
-
數學重組:通過?
res*10 + 末位
?直接構建反轉后的數字。 -
無需字符串轉換:效率高,且適用于大數字(但需注意JavaScript的數值范圍限制)。
通過這種“拆解-重組”的數學方法,可以高效地完成整數反轉。
題目描述
給定一個整數數組?nums
,要求將每個元素反轉后添加到原數組中,最終統計所有不同整數的數量。
示例:
輸入:nums = [123, 456]
輸出:4
解釋:原數組為?[123, 456]
,反轉后得到?[321, 654]
,合并后的數組為?[123, 456, 321, 654]
,共有?4
?個不同整數。
解題思路
-
核心目標
-
對每個元素執行反轉操作,生成新數字。
-
合并原數組和反轉后的所有數字,統計不重復的整數數量。
-
-
關鍵操作
-
反轉數字:將數字逐位拆解,按反方向重組(如?
123
?→?321
)。 -
去重統計:利用集合(
Set
)自動去重的特性,存儲所有數字。
-
-
算法步驟
-
初始化一個集合,存儲原數組的所有元素。
-
遍歷數組,對每個元素進行反轉,并將結果加入集合。
-
最終返回集合的大小。
-
代碼實現
var countDistinctIntegers = function (nums) {const set = new Set(nums); // 初始化集合,存儲原數組元素for (let i = 0; i < nums.length; i++) {set.add(resver(nums[i])); // 將反轉后的數字加入集合}return set.size; // 返回集合大小(即不同整數數量)
};// 反轉數字函數
const resver = (num) => {let res = 0;while (num > 0) {res = res * 10 + (num % 10); // 提取末位并重組num = parseInt(num / 10); // 去掉末位}return res;
};
代碼解析
-
集合去重(
Set
)-
new Set(nums)
?直接將原數組元素存入集合,自動去重。 -
遍歷時,通過?
set.add()
?將反轉后的數字加入集合,避免重復存儲。
-
-
反轉函數?
resver
-
逐位提取:
num % 10
?獲取末位數字(如?123 % 10 = 3
)。 -
重組數字:
res = res * 10 + 末位
?將新數字左移后填入末位(如?0 → 3 → 32 → 321
)。 -
去掉末位:
parseInt(num / 10)
?去掉已處理的末位(如?123 → 12
)。
-
-
邊界處理
-
數字0:若?
num = 0
,循環直接結束,返回?res = 0
,確保反轉結果正確。 -
末尾0:如?
120
?反轉后為?21
,自動忽略前導零。
-
復雜度分析
-
時間復雜度:
-
反轉單個數字的時間為?
O(d)
(d
?為數字的位數)。 -
遍歷數組的時間為?
O(n)
,總時間復雜度為?O(n·d)。
-
-
空間復雜度:
-
集合存儲最多?
2n
?個元素(原數組和反轉結果),空間復雜度為?O(n)。
-
示例演示
以輸入?nums = [123, 121]
?為例:
-
原數組元素存入集合:
Set {123, 121}
。 -
反轉?
123
?得到?321
,集合變為?{123, 121, 321}
。 -
反轉?
121
?得到?121
(與原數字相同),集合保持?{123, 121, 321}
。 -
最終結果:
3
?個不同整數。
總結
-
集合去重:利用?
Set
?特性高效去重,避免手動判斷重復。 -
逐位反轉:通過數學運算逐位拆解和重組,無需字符串轉換,時間復雜度低。
-
適用性:該方法適用于大整數場景(需注意 JavaScript 的數值范圍限制)。
通過結合集合的自動去重和數學反轉方法,代碼簡潔高效地解決了問題。