TS數(shù)據(jù)結(jié)構(gòu)與算法之獲取1-10000之前所有的對稱數(shù)(回文數(shù))

問題

  • 求 1-10000 之間的所有對稱數(shù)(回文)
  • 如:1,2段多,11首量,22,101进苍,232加缘,1221...

思路1-使用數(shù)組反轉(zhuǎn)、比較

  • 數(shù)字轉(zhuǎn)換為字符串觉啊,再轉(zhuǎn)換為數(shù)組
  • 數(shù)組 reverse, 再 join 為字符串
  • 前后字符串進行對比

代碼實現(xiàn)

/**
 * 查詢1-max所有對稱數(shù)(數(shù)組反轉(zhuǎn))
 */
export const findPalindromeNumbers1 = (max: number): number[] => {
  if (max <= 0) return [];

  const res = [];

  for (let i = 1; i <= max; i++) {
    const s = i.toString();
    // 反轉(zhuǎn)后比較
    if (s === s.split('').reverse().join('')) {
      res.push(i);
    }
  }

  return res;
}

思路2-字符串頭尾比較

  • 數(shù)字轉(zhuǎn)換為字符串
  • 字符串頭尾字符比較
  • (也可以使用棧生百,像括號匹配,但要注意奇偶數(shù))

代碼實現(xiàn)

/**
 * 查詢1-max所有對稱數(shù)(字符串頭尾比較)
 */
 export const findPalindromeNumbers2 = (max: number): number[] => {
  if (max <= 0) return [];

  const res = [];
  
  for (let i = 1; i <= max; i++) {
    const s = i.toString();
    // 字符串頭尾比較
    let startIndex = 0; // 字符串開始位置
    let endIndex = s.length - 1; // 字符串結(jié)束位置
    let allEqual = true;

    while (startIndex < endIndex) {
      if (s[startIndex] !== s[endIndex]) {
        allEqual = false;
        break;
      }

      // 繼續(xù)比較
      startIndex ++;
      endIndex --;
    }

    if (allEqual) {
      res.push(i);
    }
  }

  return res;
}

思路3 - 生成翻轉(zhuǎn)數(shù)

  • 使用 % 和 Math.floor 生成反轉(zhuǎn)數(shù)
  • 前后數(shù)字進行對比
  • (全程操作數(shù)字柄延,沒有字符串類型)

代碼實現(xiàn)

/**
 * 查詢1-max所有對稱數(shù)(翻轉(zhuǎn)數(shù)字)
 */
 export const findPalindromeNumbers3 = (max: number): number[] => {
  if (max <= 0) return [];

  const res = [];
  
  for (let i = 1; i <= max; i++) {
    let n = i;
    // 存儲翻轉(zhuǎn)數(shù)
    let val = 0;

    // 生成翻轉(zhuǎn)數(shù) 通過 %取余 獲取到末端數(shù),通過 /除法 進行降位
    while (n) {
      val = val * 10 + n % 10;
      n = Math.floor(n / 10);
    }

    if (val === i) {
      res.push(i);
    }
  }

  return res;
}

功能測試

export const findPalindromeFunctionalTest = () => {
  const res = findPalindromeNumbers3(200);
  console.log(res);
};

單元測試

/**
 * @description 查詢對稱數(shù)單元測試
 */
describe('查詢對稱數(shù)', () => {
  test('正常情況', () => {
    const res = findPalindromeNumbers3(200);
    expect(res.length).toBe(28);
  });

  test('max 小于等于 0', () => {
    const res = findPalindromeNumbers3(-1);
    expect(res).toEqual([]);
  });
});

執(zhí)行 yarn jest:

PASS  tests/find-palindrome-numbers.test.ts
  查詢對稱數(shù)
    ? 正常情況 (4 ms)
    ? max 小于等于 0 (29 ms)

性能測試

分別使用三種方式查詢100W以內(nèi)所的對稱數(shù)

export const findPalindromePerformanceTest = () => {
  console.time('findPalindromeNumbers1');
  findPalindromeNumbers1(100 * 10000);
  console.timeEnd('findPalindromeNumbers1');

  console.time('findPalindromeNumbers2');
  findPalindromeNumbers2(100 * 10000);
  console.timeEnd('findPalindromeNumbers2');

  console.time('findPalindromeNumbers3');
  findPalindromeNumbers3(100 * 10000);
  console.timeEnd('findPalindromeNumbers3');
}

結(jié)果:

* findPalindromeNumbers1: 631.39599609375 ms
* findPalindromeNumbers2: 49.354248046875 ms
* findPalindromeNumbers3: 37.335693359375 ms

性能分析

  • 思路1 - 看似是 O(n)蚀浆,但數(shù)組轉(zhuǎn)換、操作都需要時間搜吧,所以慢
  • 思路2 VS 思路3市俊,操作數(shù)字更快(電腦原型就是計算器)
  • 思路2要用棧,不合適滤奈。因為棧也一般用數(shù)組實現(xiàn)摆昧,會慢

盡量不要轉(zhuǎn)換數(shù)據(jù)結(jié)構(gòu),尤其數(shù)組這種有序結(jié)構(gòu)蜒程,盡量不要用內(nèi)置API绅你,如reverse,不好識別復(fù)雜度昭躺。數(shù)字操作最快忌锯,其次是字符串。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末领炫,一起剝皮案震驚了整個濱河市偶垮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖似舵,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脚猾,死亡現(xiàn)場離奇詭異,居然都是意外死亡砚哗,警方通過查閱死者的電腦和手機龙助,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛛芥,“玉大人泌参,你說我怎么就攤上這事〕?眨” “怎么了沽一?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漓糙。 經(jīng)常有香客問我铣缠,道長,這世上最難降的妖魔是什么昆禽? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任蝗蛙,我火速辦了婚禮,結(jié)果婚禮上醉鳖,老公的妹妹穿的比我還像新娘捡硅。我一直安慰自己,他們只是感情好盗棵,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布壮韭。 她就那樣靜靜地躺著,像睡著了一般纹因。 火紅的嫁衣襯著肌膚如雪喷屋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天瞭恰,我揣著相機與錄音屯曹,去河邊找鬼。 笑死惊畏,一個胖子當(dāng)著我的面吹牛恶耽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颜启,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼偷俭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了农曲?” 一聲冷哼從身側(cè)響起垢夹,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤识腿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體郑原,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年是偷,在試婚紗的時候發(fā)現(xiàn)自己被綠了感挥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡冻辩,死狀恐怖猖腕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恨闪,我是刑警寧澤倘感,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站咙咽,受9級特大地震影響老玛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜钧敞,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一蜡豹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧溉苛,春花似錦镜廉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寂玲,卻和暖如春视乐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背敢茁。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工佑淀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人彰檬。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓伸刃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逢倍。 傳聞我的和親對象是個殘疾皇子捧颅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容