まん中から広げて回文になっている部分文字列を全部数える

文字列の続いた一部のうち、前から読んでも後ろから読んでも同じになる物がいくつあるかを数えます。回文のまん中を 1 つずつ決め、左右の 2 本の指を外へ広げて数える練習です。

海外で定番の問題リスト 4 本には入っていません

問題

文字列 s を受け取ります。s の続いた一部 (部分文字列) のうち、前から読んでも後ろから読んでも同じになる物 (回文) がいくつあるかを返す関数を書いてください。

  • 中身が同じでも、s の中の場所が違えば別々に数えます。たとえば "aa" の 1 文字目の "a" と 2 文字目の "a" は 2 つです
  • 1 文字だけの部分文字列も回文として数えます
  • s の長さは 1 以上 1000 以下で、英小文字だけです

入力と出力の例

例 1

1 文字の物が 4 つ、"oo" が 1 つ、"noon" が 1 つで 6 つです。

s = "noon"
6

例 2

1 文字の物が 5 つ、"eve" と "level" で 7 つです。

s = "level"
7

例 3

同じ文字が続かず、まん中を挟んで同じ文字もないので、1 文字の物だけです。

s = "code"
4

面接での聞かれ方

面接では、最も長い回文を探す問題と組で出されることが多いです。

  • 「文字列の中に、回文の部分文字列はいくつありますか」
  • 最初に「同じ中身でも場所が違えば別に数えますか?」「1 文字も数えますか?」と確かめられるかを見られます
  • 全部の部分文字列を作って確かめる O(n³) の書き方から、O(n²) へ下げられるかを見られます

数え方の決まりは、例を 1 つ手で数えて面接官とそろえておくと、後でずれません。

ヒント

まだ開いていません

付箋は 4 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

アルゴリズムのチートシートの「配列と文字列」に、この型の要点を表とコードでまとめています。

配列と文字列の問題は、全部の組を調べると手間が大きくなる所を、窓や左右の添字で減らす形が多いです。

main.py
def count_palindromes(s: str) -> int:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(count_palindromes("noon"))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します