Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでターゲット文字より大きい最小の文字を二分探索で見つける方法

ソート済みの小文字アルファベットのリスト letters と、ターゲットとなる文字 t が与えられたとき、リストの中から「t よりも大きい文字のうち最小のもの」を探す問題を考えてみましょう。

このとき、文字は循環(ラップアラウンド)するとします。つまり、target = 'z' で letters = ['a', 'b'] のような場合、'z' より大きい文字が存在しないため、先頭に戻って答えは 'a' になります。

例えば、入力が ["c", "f", "j"] で target が 'a' の場合、'a' より大きい最小の文字は 'c' なので、出力は 'c' となります。

解き方のアプローチ:二分探索

リストがソート済みであるため、二分探索(バイナリサーチ)を使えば O(log n) の計算量で効率的に解くことができます。手順は以下の通りです。

  • 左端のインデックス l を 0 に初期化する
  • 右端のインデックス r を「リストのサイズ − 1」に初期化する
  • l ≤ r の間、以下を繰り返す
    • mid := (l + r) // 2(中央のインデックス)
    • letters[mid] > target ならば、r := mid − 1(答えの候補は左側にある)
    • そうでなければ、l := mid + 1(答えの候補は右側にある)
  • ループ終了後、letters[l % リストのサイズ] を返す

最後の「剰余演算(mod)」がポイントです。ターゲットより大きい文字が見つからなかった場合、l がリストの範囲外になるため、mod を取ることで先頭の文字に wrap around させることができます。

実装例

class Solution:
    def nextGreatestLetter(self, letters, target):
        l = 0
        r = len(letters) - 1
        while l <= r:
            mid = (l + r)//2
            if letters[mid] > target:
                r = mid -1
            else:
                l = mid + 1
        return letters[l % len(letters)]
ob = Solution()
print(ob.nextGreatestLetter(["c", "f", "j"], "a"))

入力

["c", "f", "j"], "a"

出力

c

まとめ

このように、ソート済みの文字リストからターゲットより大きい最小の文字を求める問題は、二分探索と剰余演算を組み合わせることでシンプルかつ高速に解決できます。線形探索では O(n) かかるところを、O(log n) まで削減できるのが大きなメリットです。

  1. Pythonでxより大きい最小の整数を求める方法|math.ceil()関数の使い方を解説

    Pythonで「xより大きい最小の数」を求めるには? Pythonでは、組み込みモジュール math に含まれる ceil() 関数を使うことで、指定した数値以上の最小の整数(天井値)を簡単に求めることができます。 ceil() は「切り上げ」を行う関数で、引数に渡した数値より大きい、または等しい最小の整数を返します。小数点以下の値に関係なく、常に上方向へ丸められるのが特徴です。 math.ceil() の基本的な使い方 まずは具体的なコード例を見てみましょう。 >>> x = 6.67 >>> import math >>> math.

  2. Pythonで最小公倍数(LCM)を求める方法をわかりやすく解説

    最小公倍数(LCM)とは2つ(またはそれ以上)の数の最小公倍数(LCM:Least Common Multiple)とは、それらすべての数で割り切れる最も小さい数のことです。例えば、12と20の場合、両方の数で割り切れる最小の数は60となります。基本的な求め方シンプルなアルゴリズムは以下の手順で構成されます。まず、与えられた2つの数のうち大きい方を取得します。その値から順に1ずつ増やしながら、両方の数で割り切れる最初の数を探します。見つかった数が最小公倍数(LCM)です。サンプルコードx=12 y=20 if x > y: greater = x else: greate