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

Pythonで、部分リストを並べ替えるだけでリスト全体が昇順にソートされる最短の範囲を見つける方法

数値のリスト nums が与えられたとき、その一部を並べ替えるだけでリスト全体が昇順にソートされるような、最短の部分リスト(サブリスト)の長さを求める問題について解説します。

問題の例

たとえば、入力が nums = [1, 2, 5, 4, 9, 10] の場合、出力は 2 になります。これは、部分リスト [5, 4] を並べ替えるだけで、リスト全体が [1, 2, 4, 5, 9, 10] という昇順の状態になるためです。

解き方のアルゴリズム

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

  • f := -1l := -1 として初期化する
  • lst := リスト nums をソートしたコピーを作成する
  • i を 0 から nums のサイズまで繰り返す
    • nums[i]lst[i] が異なる場合
      • f が -1 であれば、f := i を代入
      • それ以外の場合は、l := i を代入
  • ループ終了後、lf がどちらも -1 であれば 0 を返す(すでにソート済みであることを意味する)
  • それ以外の場合は、l - f + 1 を返す

考え方のポイント

このアプローチの鍵となるのは、元のリストとソート済みリストを位置ごとに比較することです。最初に不一致が発生した位置が並べ替えが必要な範囲の始点となり、最後に不一致が発生した位置が終点となります。この2つの位置に挟まれた区間の長さが、求める答えになります。

実装例

以下の実装を見ると、理解がより深まるでしょう。

class Solution:
   def solve(self, nums):
      f = -1
      l = -1
      lst = sorted(nums)
      for i in range(len(nums)):
         if nums[i] != lst[i]:
            if f == -1:
               f = i
            else:
               l = i
      if l == -1 and f == -1:
         return 0
      return l - f + 1

ob = Solution()
print(ob.solve([1, 2, 5, 4, 9, 10]))

入力

[1, 2, 5, 4, 9, 10]

出力

2

計算量について

このアルゴリズムでは、リストのソートに O(n log n) の時間がかかるため、全体の時間計算量は O(n log n) となります。また、ソート済みのコピーを保持する必要があるため、空間計算量は O(n) です。


  1. Pythonでソート済みリスト内のすべてのペアの絶対差の合計を求めるプログラム

    ソートされた数値リスト nums が与えられたとき、リスト内のすべての数値ペアの絶対差の合計を求めることを考えます。ここで、(i, j) と (j, i) は異なるペアとして扱います。答えが非常に大きくなる場合は、結果を 10^9+7 で割った余りを返します。例えば、nums = [2, 4, 8] の場合、|2 - 4| + |2 - 8| + |4 - 2| + |4 - 8| + |8 - 2| + |8 - 4| を計算することになるため、出力は 24 となります。解法のアプローチこの問題を効率的に解くために、以下の手順に従います。m = 10^9 + 7 とします。total を 0

  2. 【Python】リスト内の2つの数値を足して合計がkになるペアを探すプログラム

    数値のリスト nums ともう一つの数値 k が与えられたとき、リスト内の任意の2つの数値を足した合計が k と一致するかどうかを判定するプログラムを作成します。ただし、同じ要素を2回使用することはできません。また、数値には負の数や0が含まれる場合もあります。例えば、入力が nums = [45, 18, 9, 13, 12]、k = 31 の場合、18 + 13 = 31 となるため、出力は True になります。解法のアプローチこの問題は「セット(集合)」を使うことで効率的に解けます。各数値に対して、それとペアになるべき値(k - num、いわゆる補数)を事前にセットへ記録しておき、後から