【Python】長さ3の増加部分列(トリプレット)を判定するアルゴリズムを解説
ソートされていない整数型の配列が与えられたとき、その中に「長さ3の増加部分列」が存在するかどうかを判定する問題を考えます。本記事では、Pythonを使ってこの問題を線形時間で解く効率的なアルゴリズムを紹介します。
問題の定義
正式には、この関数は以下の条件を満たす必要があります。
- インデックス i、j、k が存在し、0 ≤ i < j < k ≤ n-1 の条件下で arr[i] < arr[j] < arr[k] を満たす場合は true を返す
- そのような組み合わせが存在しない場合は false を返す
解法のアプローチ
この問題は、2つの変数 small と big を使う貪欲法(グリーディー法)により、時間計算量 O(n)、空間計算量 O(1) で解くことができます。手順は以下の通りです。
- small := 無限大、big := 無限大 として初期化する
- 配列の各要素 i について以下を繰り返す
- i <= small の場合:small := i と更新する
- それ以外で i <= big の場合:big := i と更新する
- どちらにも当てはまらない場合:i は small よりも大きく、big よりも後に出現した値であるため、増加トリプレットの存在が確定し、true を返す
- ループが終了しても true が返らなければ、false を返す
実装例
class Solution(object): def increasingTriplet(self, nums): small,big = 100000000000000000000,100000000000000000000 for i in nums: if i <= small: small = i elif i<=big: big = i else : return True return False ob1 = Solution() print(ob1.increasingTriplet([5,3,8,2,7,9,4]))
入力
[5,3,8,2,7,9,4]
出力
True
アルゴリズムのポイント
このアルゴリズムの鍵となるのは、small と big の更新ロジックです。small には「これまでに見つかった最小値」、big には「small 以降に現れた、small より大きい値のうち最小のもの」が保持されます。したがって、ある要素が big よりも大きければ、必ず「small < big < その要素」という増加関係が成立していることになります。
なお、実務のコードでは巨大な定数の代わりに float('inf') を使うと、より安全で可読性の高い実装になります。
-
Pythonで関数から複数の値を返す5つの方法【タプル・辞書・クラス・リスト・ジェネレータ】
Pythonの関数は、複数の値を一度に返すことができます。返された値はそのまま変数に格納でき、関数が返せるのは1つの変数だけとは限りません。0個、1個、2個、それ以上の値でも自由に返せます。実は、この「複数の値を返せる」という性質はPythonの標準的な機能です。C++やJavaなど、多くの他のプログラミング言語では利用できない便利な特徴といえます。関数から複数の値を返すには、目的に応じてタプル、リスト、辞書などのオブジェクトを活用します。本記事では、代表的な5つの方法をコード例とともにわかりやすく解説します。方法1:タプル(tuple)を使うdef func(x): y0 = x +
-
Pythonの関数から複数の値を返す4つの方法【タプル・リスト・辞書・クラス】
はじめに Pythonでは、関数から複数の値をまとめて返すことが標準機能として簡単に行えます。具体的には、タプル、リスト、辞書(dict)、そしてユーザー定義クラスのオブジェクトという4つの形式が利用できます。 それぞれの方法を、実際のコード例とともに順番に見ていきましょう。 方法1:タプルとして返す(最も一般的) Pythonで最もよく使われるのがこの方法です。return a, bのようにカンマで区切って値を並べると、自動的にタプルとしてまとめて返されます。受け取る側ではアンパックを使って、個別の変数へ直接代入することも可能です。 >>> def function():