• 14、获取1-10000之间的所有回文数


    对称数

    • 求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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    功能测试

    getPalindrome1(100)
    
    • 1

    结果

    [
       1,  2,  3,  4,  5,  6,  7,
       8,  9, 11, 22, 33, 44, 55,
      66, 77, 88, 99
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    思路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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    功能测试

    getPalindrome2(100)
    
    • 1

    结果

    [
       1,  2,  3,  4,  5,  6,  7,
       8,  9, 11, 22, 33, 44, 55,
      66, 77, 88, 99
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    思路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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    功能测试

    getPalindrome3(100)
    
    • 1

    结果

    [
       1,  2,  3,  4,  5,  6,  7,
       8,  9, 11, 22, 33, 44, 55,
      66, 77, 88, 99
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    单元测试

    describe('回文数',() => {
      it('正常情况', () => {
        const res = getPalindrome1(200)
        expect(res.length).toBe(28)
      })
    
      it('max 小于或者等于 0', () => {
        const res = getPalindrome1(0)
        expect(res).toEqual([])
      })
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    性能测试

    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    打印结果

    getPalindrome1: 295.913ms
    getPalindrome2: 35.2ms
    getPalindrome3: 28.102ms
    
    • 1
    • 2
    • 3

    性能分析

    • 思路1-看似是O(n),但是数组转换、操作都需要时间,很慢
    • 思路2 VS 思路3,操作数字更快(电脑原型就是计算器)
    • 思路2要用栈,不合适,因为栈也一般用数组实现,会慢

    总结

    • 尽量不要转换数据结构,尤其数组这种有序结构
    • 尽量不要用内置API,如reverse,不好识别复杂度
    • 数字操作最快,其次是字符串
  • 相关阅读:
    机器视觉在艺术鉴赏和文物修复中的应用与挑战
    Word控件Spire.Doc 【段落处理】教程(三):在 C#、VB.NET 中管理词标题以形成目录
    电脑可以通过蓝牙发送文件吗?电脑蓝牙怎么发送文件
    性能测试监控-java分析工具Arthas
    flutter实现透明appbar(一)
    Linux-编译器
    win10+yolov5+pytorch+gpu
    Git操作复习笔记
    51单片机学习:直流电机实验
    初识Spring框架及其特点
  • 原文地址:https://blog.csdn.net/qq_36362721/article/details/127680780