Pythonでリスト内の連続する偶数要素を交換する方法
問題の概要
数値のリスト nums が与えられたとき、「連続して現れる偶数」同士をペアごとに入れ替えることを考えます。
たとえば、入力が nums = [4, 5, 6, 8, 10] の場合、出力は [6, 5, 4, 10, 8] となります。
解法のアプローチ
この問題は、一時変数を1つ用意するだけでシンプルに解決できます。手順は以下の通りです。
- 一時変数
tempをNoneで初期化する iを 0 からリストの要素数まで順にループさせるnums[i]が偶数(2で割った余りが0)の場合:tempがNoneでなければ、nums[i]とnums[temp]を交換し、tempをNoneに戻す- そうでなければ、現在のインデックス
iをtempに記録する
- 最後に
numsを返す
ポイントは、最初に見つけた偶数のインデックスを temp に保持しておき、次の偶数が現れた時点で2つを交換するという仕組みです。これにより、リスト内の偶数どうしが出現順にペアとなって入れ替わります。
Pythonでの実装例
class Solution:
def solve(self, nums):
temp = None
for i in range(len(nums)):
if nums[i] % 2 == 0:
if temp is not None:
nums[i], nums[temp] = nums[temp], nums[i]
temp = None
else:
temp = i
return nums
ob = Solution()
print(ob.solve([4, 5, 6, 8, 10]))入力
[4, 5, 6, 8, 10]
出力
[6, 5, 4, 10, 8]
動作の流れを追ってみる
入力 [4, 5, 6, 8, 10] の場合、処理は次のように進みます。
- i=0: nums[0]=4 は偶数。temp は None なので、temp=0 を記録
- i=1: nums[1]=5 は奇数なのでスキップ
- i=2: nums[2]=6 は偶数。temp=0 があるため nums[0] と nums[2] を交換 →
[6, 5, 4, 8, 10]。temp を None に戻す - i=3: nums[3]=8 は偶数。temp は None なので、temp=3 を記録
- i=4: nums[4]=10 は偶数。temp=3 があるため nums[3] と nums[4] を交換 →
[6, 5, 4, 10, 8]
このアルゴリズムは、リストを一度だけ走査すればよいため、時間計算量 O(n)、追加のメモリも不要で空間計算量 O(1) と非常に効率的です。
-
Pythonで部分集合(冪集合)をすべて生成する方法を解説
はじめにある数値の集合が与えられたとき、その集合から作れるすべての部分集合を生成する問題を考えてみましょう。この「すべての部分集合の集まり」は冪集合(べきしゅうごう、Power Set)と呼ばれます。例えば、集合が [1, 2, 3] の場合、冪集合は次のようになります。[[], [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3]]要素数が n の集合に対して部分集合は 2n 個存在するため、n = 3 なら 8 個の部分集合が得られます。アルゴリズムの考え方:再帰による解法この問題は再帰(バックトラッキング)を使って elegantly 解くことができます
-
Pythonで解く「フェアキャンディスワップ」問題:アルゴリズムと実装をわかりやすく解説
この記事では、Pythonを使って「フェアキャンディスワップ(公平なキャンディ交換)」問題を解く方法を解説します。数式ベースのシンプルなアプローチとセット(集合)による高速な探索を組み合わせることで、効率よく答えを導き出します。 問題の概要 AさんとBさんは友人同士で、それぞれ異なるサイズのキャンディバーを持っています。ここで、A[i]はAさんが持っているi番目のキャンディバーのサイズ、B[j]はBさんが持っているj番目のキャンディバーのサイズを表します。 二人は友人なので、お互いにキャンディバーを1本ずつ交換し、交換後に両者の持つキャンディの総量(所有するキャンディバーのサイズの合計)が等し