对称数
- 求1-10000之间的所有对称数(回文数)
- 例如:0,1,2,11,22,101,232...
思路1—使用数组反转、比较
- 数字转换为字符串,在转换为数组
- 数组reverse,再join为字符串
- 前后字符串进行对比
代码实现
function getPalindrome1(max:number):number[] {
const res:number[] = []
if(max <= 0) return res
for (let i = 1; i < max; i++) {
const n = i.toString()
if (n === n.split('').reverse().join('')) {
// 数值转字符串,在分割、反转、拼接后和原数比较,一样说明是回文数
res.push(i)
}
}
return res
}
功能测试
getPalindrome1(100)
结果
[
1, 2, 3, 4, 5, 6, 7,
8, 9, 11, 22, 33, 44, 55,
66, 77, 88, 99
]
思路2—字符串头尾比较
- 数字转字符串
- 字符串头尾字符比较
- (也可以用栈,像括号匹配,但要注意奇数和偶数)
代码实现
function getPalindrome2(max:number):number[] {
const res:number[] = []
if(max <= 0) return res
for (let i = 1; i <= max; i++) {
const n = i.toString()
const len = n.length
let flag = true // 判断是否是回文数标识
let startIndex = 0 // 字符串头部
let endIndex = len -1 // 字符串尾部
while(startIndex < endIndex) {
if (n[startIndex] !== n[endIndex] ) {
flag = false
break
} else {
// 两边向中间推进,继续比较
startIndex++
endIndex--
}
}
if (flag) {
res.push(i)
}
}
return res
}
功能测试
getPalindrome2(100)
结果
[
1, 2, 3, 4, 5, 6, 7,
8, 9, 11, 22, 33, 44, 55,
66, 77, 88, 99
]
思路3—生成翻转数
- 使用% 和Math.floor 生成翻转数
- 前后数字进行比较
- (全程操作数字,没有字符串类型)
代码实现
function getPalindrome3(max:number):number[] {
const res:number[] = []
if(max <= 0) return res
for (let i = 1; i <= max; i++) {
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
}
功能测试
getPalindrome3(100)
结果
[
1, 2, 3, 4, 5, 6, 7,
8, 9, 11, 22, 33, 44, 55,
66, 77, 88, 99
]
单元测试
describe('回文数',() => {
it('正常情况', () => {
const res = getPalindrome1(200)
expect(res.length).toBe(28)
})
it('max 小于或者等于 0', () => {
const res = getPalindrome1(0)
expect(res).toEqual([])
})
})
性能测试
console.time('getPalindrome1')
getPalindrome1(100 * 10000)
console.timeEnd('getPalindrome1')
console.time('getPalindrome2')
getPalindrome2(100 * 10000)
console.timeEnd('getPalindrome2')
console.time('getPalindrome3')
getPalindrome3(100 * 10000)
console.timeEnd('getPalindrome3')
打印结果
getPalindrome1: 295.913ms
getPalindrome2: 35.2ms
getPalindrome3: 28.102ms
性能分析
- 思路1-看似是O(n),但是数组转换、操作都需要时间,很慢
- 思路2 VS 思路3,操作数字更快(电脑原型就是计算器)
- 思路2要用栈,不合适,因为栈也一般用数组实现,会慢
总结
- 尽量不要转换数据结构,尤其数组这种有序结构
- 尽量不要用内置API,如reverse,不好识别复杂度
- 数字操作最快,其次是字符串