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

Pythonで配列が「ソート済み+回転」状態かどうかを判定するプログラム


問題の概要

nums という配列が与えられたとき、その配列が「もともと非減少順(昇順)にソートされていたものを、何度か(0回でも可)回転させた結果」になっているかどうかを判定します。配列には重複した要素が含まれている場合もあります。

たとえば、入力が nums = [12,15,2,5,6,9] の場合、出力は True になります。これは、ソート済みの配列 [2,5,6,9,12,15] を右に2回転させると [12,15,2,5,6,9] になるためです。

解決のアプローチ

この問題は、次の手順で解くことができます。

  1. 変数 j を 0 に初期化します。
  2. j が「配列の長さ − 1」未満であり、かつ nums[j] ≤ nums[j+1] が成り立っている間、j を 1 ずつ増やします。これにより、昇順が崩れる位置(境界)を見つけます。
  3. res を、「インデックス j+1 以降の部分配列」と「先頭からインデックス j までの部分配列」を連結したものとして作成します。これで回転前の状態に戻した配列が得られます。
  4. i を 0 から res の長さ − 2 まで動かしながら確認し、res[i] > res[i+1] となる箇所があれば False を返します。
  5. 最後まで昇順が崩れなければ、True を返します。

Pythonでの実装例

理解を深めるために、以下の実装例を見てみましょう。

def solve(nums):
    j = 0
    while (j < len(nums) - 1 and nums[j] <= nums[j + 1]):
        j += 1
    res = nums[j + 1 : len(nums)] + nums[0:j + 1]
    for i in range(len(res) - 1):
        if res[i] > res[i + 1]:
            return False
    return True

nums = [12,15,2,5,6,9]
print(solve(nums))

入力

[12,15,2,5,6,9]

出力

True

アルゴリズムのポイント

このアルゴリズムでは、まず昇順が崩れる最初の位置を特定し、そこで配列を分割して連結し直すことで「回転を解除」します。そのうえで全体が再び昇順になっていれば、元の配列は「ソート済み+回転」だったことになります。

計算量は O(n)、追加で必要なメモリも O(n)(連結用の新しい配列 res を作成するため)です。重複要素があっても比較条件に「≤」を使っているため、正しく判定できる点も特徴です。


  1. Pythonで挿入ソート(Insertion Sort)を実装する方法:アルゴリズムとサンプルコードを徹底解説

    この記事では、Python 3.x(およびそれ以前のバージョン)における挿入ソートの実装方法について詳しく解説します。挿入ソートは、トランプの手札を整理するイメージに近い、直感的で理解しやすいソートアルゴリズムです。挿入ソートのアルゴリズム挿入ソートは以下の手順で動作します。入力要素を順番に走査し、各反復ごとにソート済みの配列部分を少しずつ拡張していきます。現在注目している要素(キー)を、ソート済み部分の中で最も大きい値と比較します。キーがその値より大きければ、要素は元の位置のまま次の要素へ進みます。そうでなければ、ソート済み配列内の正しい位置を探し出し、そこへ移動させます。具体的には、ソート

  2. Pythonで学ぶ挿入ソート(Insertion Sort)の仕組みと実装方法

    この記事では、Python 3.xにおける挿入ソート(Insertion Sort)の基本的な考え方と、実際のコードによる実装方法をわかりやすく解説します。 挿入ソートのアルゴリズム 挿入ソートは、配列を「整列済みの部分」と「未整列の部分」に分け、未整列の要素を一つずつ取り出して、整列済み部分の正しい位置に挿入していくシンプルなソート手法です。処理の手順は以下の通りです。 1. 各反復ごとに整列済みの配列を少しずつ拡大しながら、入力要素を走査する。 2. 現在の要素(キー)を、整列済み配列内の最大値と比較する。 3. キーがその最大値より大きければ、要素はそのままの位置に置かれ、 次の要