目录
核心思想:数字的“拆分”与“重组”
分步拆解(以输入 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ⁿ⁻¹ + ... + z×10⁰ 
反转后的数字则是:
res = z×10ⁿ + ... + b×10¹ + 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 的数值范围限制)。
 
通过结合集合的自动去重和数学反转方法,代码简洁高效地解决了问题。