1-10000 之间的对称数(回文)

186 阅读1分钟

1-10000 之间的对称数(回文)

题目

打印 1-10000 之间的对称数

使用数组反转

  • 数字转换为字符串
  • 字符串转换为数组 reverse ,再 join 生成字符串
  • 比较前后的字符串

使用数组反转

  • 数字转换为字符串
  • 字符串转换为数组 reverse ,再 join 生成字符串
  • 比较前后的字符串

使用字符串头尾比较

  • 数字转换为字符串
  • 字符串头尾比较

还可以使用(但栈会用到数组,性能不如直接操作字符串)

  • 数字转换为字符串,求长度
  • 如果长度是偶数,则用栈比较
  • 如果长度是奇数,则忽略中间的数字,其他的用栈比较

生成反转数

  • 通过 %Math.floor 将数字生成一个反转数
  • 比较前后的数字

性能分析

时间复杂度看似相当,都是 O(n)

但 方案1 涉及到了数组的转换和操作,就需要耗费大量的时间

  • 数组 reverse 需要时间
  • 数组和字符串的转换需要时间

方案 2 3 比较,数字操作最快。电脑的原型就是计算器,所以处理数字是最快的。

/**
 * 查询 1-max 的所有对称数(数组反转)
 * @param max 最大值
 */
function findPalindromeNum1(max) {
  const res = [];
  if (max <= 0) return res;
  for (let i = 1; i <= max; i++) {
    const ele = i.toString();
    if (ele === ele.split('').reverse().join('')) {
      res.push(ele);
    }
  }
  return res;
}
/**
 * 查询 1-max 的所有对称数(字符串前后比较)
 * @param max 最大值
 */
function findPalindromeNum2(max) {
  const res = [];
  if (max <= 0) return res;

  for (let i = 1; i <= max; i++) {
    const ele = i.toString();
    let flag = true;
    let startIndex = 0;
    let endIndex = ele.length - 1;
    while (startIndex < endIndex) {
      if (ele[startIndex] === ele[endIndex]) {
        startIndex++;
        endIndex--;
      } else {
        flag = false;
        break;
      }
    }
    if (flag) res.push(ele);
  }

  return res;
}
/**
 * 查询 1-max 的所有对称数(翻转数字)
 * @param max 最大值
 */

function findPalindromeNum3(max) {
  const res = [];
  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;
}