Pythonで解く「最小範囲 I」問題:配列の最大値と最小値の差を最小化する方法
問題概要
整数からなる配列 A が与えられます。各要素 A[i] に対して、範囲 [-K, K] 内の任意の値 x を選び、それを A[i] に加算することができます。この操作をすべての要素に適用した結果として得られる新しい配列を B とします。このとき、B の最大値と最小値の差が取りうる最小値を求めてください。
例えば、入力が A = [0, 10]、K = 2 の場合を考えてみましょう。操作後の配列を B = [2, 8] とすることができ、最大値 8 と最小値 2 の差は 6 となるため、出力は 6 になります。
アプローチ
この問題は実は非常にシンプルです。ポイントは次の通りです。
- 最大値をできるだけ小さくしたいなら、配列 A の最大値から K を引くのが最善
- 最小値をできるだけ大きくしたいなら、配列 A の最小値に K を足すのが最善
- K が十分大きくて差が負になる場合、すべての要素を同じ値に揃えられるため、答えは 0
以上をまとめると、次の手順で解くことができます。
- MAX := (A の最大値)− K
- MIN := (A の最小値)+ K
- difference := MAX − MIN
- difference < 0 の場合は 0 を返す
- それ以外の場合は difference を返す
Pythonでの実装例
class Solution:
def smallestRangeI(self, A, K):
MAX = max(A) - K
MIN = min(A) + K
difference = MAX - MIN
if difference < 0:
return 0
else:
return difference
ob = Solution()
print(ob.smallestRangeI([0, 10], 2))
入力例
[0, 10], 2
出力例
6
計算量の目安
max() と min() による配列の走査がそれぞれ O(N) であるため、全体の時間計算量は O(N) となります。また、追加のメモリはほとんど不要で、空間計算量は O(1) です。
注目すべきは、答えに関係するのは配列内の「最大値」と「最小値」だけであり、それ以外の要素の値は結果に一切影響しないという点です。一見複雑そうに見える問題でも、本質を見抜けば定数個の値だけで解ける良い例と言えるでしょう。
-
Pythonで行列(マトリックス)を初期化する2つの方法
はじめに この記事では、Python 3.xにおいて2次元リストを使って行列(マトリックス)を初期化する方法を解説します。行列の初期化には大きく分けて2つのアプローチがあり、それぞれ特徴が異なります。 方法1:リスト内包表記を使う(Pythonらしい書き方) まずは、Pythonならではの直感的な初期化方法です。リスト内包表記を活用することで、内側のリスト(各行)を生成しながら、それを複数行へと一気に拡張できます。コードが簡潔になり、Pythonicなスタイルとして好まれる書き方です。 コード例 # 行数を指定 N = 3 # 列数を指定 M = 3 # リスト内包表記で行列を初期化(各要
-
Pythonの各種実装の違いを徹底解説!CPython・Cython・Jython・IronPython・PyPyの特徴とは
多くの開発者にとって「Python」という名前は馴染み深いものですが、自分が使っているシステムでどのPython実装が動いているかを意識している人は意外と少ないかもしれません。そもそも私たちが「Python」と呼んでいるものは何なのでしょうか?抽象的な言語仕様としてのPythonなのか、最も一般的な実装であるCPython(注意:Cythonではありません)なのか、それともまったく別の何か、たとえばJythonやIronPython、PyPyといった実装を指しているのでしょうか?これらの技術はよく知られており頻繁に参照されますが、その目的や役割はそれぞれ大きく異なります。本記事では、「Pyth