Pythonで合計がkに等しい4つの異なる要素を見つけられるか判定するプログラム
問題の概要
数値のリスト nums と値 k が与えられたとき、リスト内に合計が k と等しくなる4つの異なる要素が存在するかどうかを判定します。
たとえば、入力が nums = [11, 4, 6, 10, 5, 1]、k = 25 の場合、[4, 6, 10, 5] の合計が25になるため、出力は True となります。
解法のアプローチ:ソート + 双方向ポインタ法
この問題は、いわゆる「4Sum」問題と呼ばれるものです。全組み合わせを総当たりすると計算量が膨大になりますが、リストをソートしたうえで双方向ポインタ(two pointers)テクニックを使うことで、効率よく探索できます。
手順は以下の通りです。
- まずリスト
numsをソートします。 n := numsのサイズとします。iを 0 から n − 4 の範囲で繰り返します。jを i + 1 から n − 3 の範囲で繰り返します。l := j + 1、h := numsのサイズ − 1 とします。l < hの間、以下を繰り返します。summ := nums[i] + nums[j] + nums[l] + nums[h]を計算します。summ == kならTrueを返します。summ < kならl := l + 1(左ポインタを右へ移動)。- それ以外の場合は
h := h − 1(右ポインタを左へ移動)。
- すべての候補を調べても見つからなければ
Falseを返します。
ソートしておくことで、合計が小さすぎる場合は左端のポインタを進め、大きすぎる場合は右端のポインタを戻す、という操作で目的の合計値に近づけていくことができます。
実装例
それでは、実際のコードを見て理解を深めましょう。
class Solution: def solve(self, nums, k): nums.sort() n = len(nums) for i in range(n - 3): for j in range(i + 1, n - 2): l, h = j + 1, len(nums) - 1 while l < h: summ = nums[i] + nums[j] + nums[l] + nums[h] if summ == k: return True elif summ < k: l += 1 else: h -= 1 return False ob1 = Solution() nums = [11, 4, 6, 10, 5, 1] k = 25 print(ob1.solve(nums, k))
入力
[11, 4, 6, 10, 5, 1], 25
出力
True
計算量について
外側の2重ループ(i と j)に加えて、内側でポインタを動かしながら走査するため、全体の時間計算量は O(n³) となります。総当たり方式の O(n⁴) と比べると大幅に効率化されており、ソートのコスト O(n log n) を含めても十分に高速です。
-
Pythonで数値が「異なる階乗の和」として表せるかを判定するプログラム
問題の概要 正の整数 n が与えられたとき、n を互いに異なる階乗の値(1!, 2!, 3! など)の和として表すことができるかどうかを判定する問題です。 たとえば、入力が n = 144 の場合を考えてみましょう。 4! + 5! = 24 + 120 = 144 となるため、この場合の出力は True になります。 解法のアプローチ この問題は、次の手順で解くことができます。 fact を 1 で初期化し、結果を格納するための空のリスト res を用意します。また、カウンタ x を 2 とします。 fact <= n である限り、以下を繰り返して n 以下のすべての階乗をリストに
-
リスト内の要素の合計を求めるPythonプログラム
この記事では、Pythonを使ってリスト内のすべての要素の合計を求める方法について、具体的なコード例とともに解説します。問題の定義リストが入力として与えられたとき、そのリストに含まれるすべての要素の合計値を計算する必要があります。例えば、[1, 2, 3, 4, 5]というリストが与えられた場合、出力は 15(1+2+3+4+5)となります。この問題を解くためのアプローチは主に2つあります。1つは組み込み関数を使用する方法、もう1つはブルートフォース(総当たり)方式でループ処理を行う方法です。方法1:組み込み関数 sum() を使うPythonには標準で用意されている組み込み関数 sum()