Pythonで解く「最大スワップ」問題:1回の桁入れ替えで最大の数を作るアルゴリズム
問題の概要
非負整数が与えられたとき、2つの桁を高々1回だけ入れ替えることで作れる最大の数を求めます。例えば、入力が 2736 の場合、出力は 7236 になります。これは先頭の「2」と次の「7」を入れ替えた結果です。
アルゴリズムの考え方
基本となるアイデアはシンプルです。元の数の各桁を降順に並べ替えたものが理論上の最大形になります。そこで、降順ソートした配列と元の配列を左から順に比較し、初めて一致しなくなった位置を見つけます。その位置にある小さい桁を、後続の桁の中で同じ大きい数字の最も右側(最下位)の出現箇所と入れ替えることで、数値を最大化できます。できるだけ下位の桁と交換するのがポイントで、これにより入れ替えによる増分が最大になります。
解法の手順
num:数値を各桁に分解し、リスト化しますnum1:numを降順にソートしますindexを 0 で初期化しますindexがnumの長さ未満である間、以下を繰り返しますnum1[index]とnum[index]が異なる場合a:=numのindex+1以降の部分配列aを反転させますa:=len(a) − a.index(num1[index]) + index + 1 − 1(大きい数字の最も右側の位置を算出)num[index]とnum[a]を入れ替えます- ループを抜けます
indexを 1 増やします
numの各桁を連結して整数に変換します- 結果を返します
Pythonでの実装例
以下の実装を見ると、処理の流れがより理解しやすくなります。
class Solution:
def maximumSwap(self, num):
num = list(map(int,list(str(num))))
num1 = sorted(num,reverse=True)
index=0
while index<len(num):
if num1[index]!=num[index]:
a = num[index+1:]
a.reverse()
a=len(a) - a.index(num1[index])+index+1 -1
num[index],num[a] = num[a],num[index]
break
index+=1
return int("".join(str(x) for x in num))
ob1 = Solution()
print(ob1.maximumSwap(5397))
入力
5397
出力
9357
この例では、先頭付近の「5」と最大の「9」を入れ替えることで、5397 → 9357 という最大値が得られます。
計算量について
この手法では降順ソートを行うため、時間計算量は O(n log n)、桁を保持するリストの分だけ空間計算量は O(n) となります。なお、各数字の最後の出現位置をあらかじめ記録しておく方式を使えば、O(n) 時間で解くことも可能です。
-
Pythonで最大部分配列(Maximum Subarray)問題を解く方法【動的計画法】
最大部分配列問題とは 整数配列 A が与えられたとき、長さが 1 以上の連続する部分配列の中で、要素の合計が最大になるものを見つけ、その合計値を返すことを考えます。 例えば、配列 A = [-2, 1, -3, 4, -1, 2, 1, -5, 4] の場合、最大の合計は 6 となり、これは部分配列 [4, -1, 2, 1] の合計に相当します。 解き方:動的計画法(DP) この問題は、動的計画法(Dynamic Programming)を使うことで効率的に解くことができます。手順は以下の通りです。 配列 A と同じサイズの配列 dp を定義し、0 で初期化する dp[0] := A[0]
-
【Python入門】3つの数値から最大値を求める方法
3つの数値 a、b、c が与えられたとき、その中で最も大きい要素(最大値)を見つけるのが今回の課題です。ここでは、Pythonのリストと組み込み関数 max() を使ったシンプルな方法を、初心者向けにわかりやすく解説します。 実行例 入力:a = 2, b = 4, c = 3 出力:4 アルゴリズム ステップ1:ユーザーから3つの数値を入力として受け取る。 ステップ2:3つの数値をリストに格納する。 ステップ3:max() 関数を使ってリスト内の最大値 max(lst) を求める。 ステップ4:最後に最大値を出力する。 サンプルコード def maximum(a, b, c):