对称数
- 求1-10000之前的所有对称数(回文)
- 例如:0,1,2,11,22,101,232,1221
思路1 - 使用数组反转、比较
- 数字转换为字符串,再转换为数组
- 数组revers,再join为字符串
- 前后字符串比较
代码
// 数组反转
function findPalindromeNumber1(max: number): number[] {
const res: number[] = []
if (max <= 0) return res
for (let i = 0
const s = i.toString()
if (s === s.split('').reverse().join('')) {
res.push(i)
}
}
return res
}
思路2 - 字符串头尾比较
- 数字转换为字符串
- 字符串头尾字符比较
- 也可以用栈,像括号匹配,但要注意奇偶数
代码
// 字符串头尾比较
function findPalindromeNumber2(max: number): number[] {
const res: number[] = []
if (max <= 0) return res
for (let i = 0
let s = i.toString()
let length = s.length
let startIndex = 0
let endIndex = length - 1
let flag = true
if (s[startIndex] !== s[endIndex]) { flag = false
while (startIndex < endIndex) {
if (s[startIndex] !== s[endIndex]) {
flag = false
break
} else {
startIndex++
endIndex--
}
}
if (flag) {
res.push(i)
}
}
return res
}
思路3 - 生成翻转数
- 使用%和Math.floor 生成反转数
- 前后数字进行对比
- 全程操作数字,没有字符串类型
代码
// 生成翻转数
function findPalindromeNumber3(max: number): number[] {
const res: number[] = []
if (max <= 0) return res
for (let i = 0
let n = i
let rev = 0
// 生成翻转数字
while (n > 0) {
rev = rev * 10 + n % 10
n = Math.floor(n/10)
}
if(i===rev) res.push(i)
}
return res
}
测试代码
console.info(findPalindromeNumber3(200))
结果:

性能测试
console.time('findPalindromeNumbers1');
findPalindromeNumber1(100*10000)
console.timeEnd('findPalindromeNumbers1')
console.time('findPalindromeNumbers2')
findPalindromeNumber2(100 * 10000)
console.timeEnd('findPalindromeNumbers2')
console.time('findPalindromeNumbers3')
findPalindromeNumber3(100 * 10000)
console.timeEnd('findPalindromeNumbers3')

结论
- 思路1 看似是O(n),但数组转换、操作都需要时间,所以慢
- 思路2 vs 思路3 操作数字更快(电脑原型就是计算器)
- 思路2 要用栈 不合适 因为栈也用数组实现 会慢
划重点
- 尽量不要转换数据结构,尤其数组这种有序结构
- 尽量不要用内置API如reverse,不好识别复杂度
- 数字操作更快,其次是字符串