【Python】数値リストから長さ3以上の等差数列を数えるプログラム
数値のリスト nums が与えられたとき、その中に含まれる「長さ3以上の連続する等差数列」の個数を求める問題を考えます。等差数列とは、隣り合う数同士の差(公差)がすべて等しい数列のことです。
例えば、入力が nums = [6, 8, 10, 12, 13, 14] の場合、出力は 4 になります。次の4つの等差数列が見つかるためです。
- [6, 8, 10]
- [8, 10, 12]
- [6, 8, 10, 12]
- [12, 13, 14]
解法のアプローチ
この問題は、リストを一度走査するだけで解くことができます。基本的なアイデアは、「同じ差が何回連続して現れたか」をカウントし、そのカウントから等差数列の総数を算出するというものです。
具体的には、以下の手順に従います。
count := 0、ans := 0で初期化します。i を 2 から nums のサイズ未満まで繰り返します。
nums[i] - nums[i-1]がnums[i-1] - nums[i-2]と等しい場合は、countを 1 増やします。- それ以外の場合は、
ansに(count * (count + 1)) // 2を加算し、countを 0 に戻します。
ループ終了後に
countが 0 以外であれば、ansに(count * (count + 1)) // 2を加算します。ansを返します。
なぜ count × (count + 1) ÷ 2 なのか?
同じ公差が count 回連続して一致した区間では、そこから切り出せる長さ3以上の等差数列は、長さ3のものが count 個、長さ4のものが count - 1 個…と続き、合計は 1 + 2 + … + count = count × (count + 1) ÷ 2 となります。この性質を使うことで、二重ループなしに効率的に答えを求められます。
実装例
それでは、実際のコードを見てみましょう。
class Solution:
def solve(self, nums):
count = 0
ans = 0
for i in range(2, len(nums)):
if nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2]:
count += 1
else:
ans += (count * (count + 1)) // 2
count = 0
if count:
ans += (count * (count + 1)) // 2
return ans
ob = Solution()
nums = [6, 8, 10, 12, 13, 14]
print(ob.solve(nums))
入力
[6, 8, 10, 12, 13, 14]
出力
4
このアルゴリズムの時間計算量は O(n)、空間計算量は O(1) であり、リストの要素数が大きくなっても高速に動作するのが特徴です。
-
Pythonでリスト内の最小値を見つける方法を解説
この記事では、リストの中から最小の数値を見つける方法について、具体的なサンプルコードとともに詳しく解説します。問題の概要問題: 数値のリストが与えられたとき、その中に含まれる最も小さい数値を画面に表示すること。この問題を解くアプローチは主に2つあります。ひとつは sort() メソッドを使ってリストを昇順に並べ替え、先頭の要素(インデックス0)を取得する方法。もうひとつは、Pythonに標準で用意されている組み込み関数 min() を使う方法です。それぞれ順番に見ていきましょう。方法1:sort()メソッドで並べ替えて最小値を取得するまずはリストを昇順にソートし、先頭の要素を取り出す方法です。
-
PythonでリストからN個の最大要素を取得する方法
整数のリストが与えられたとき、その中からN個の大きな要素を取り出して新しいリストとして返すのが、ここでの課題です。本記事では、基本的なループ処理による方法から、Python標準ライブラリを活用した効率的な方法まで、サンプルコードとともに解説します。 例 入力 : [40, 5, 10, 20, 9] N = 2 出力 : [40, 20] アルゴリズム 整数のリストと、取得する要素数Nを受け取ります。 N回のループを実行します。 各ループでリスト内の最大値を探し、新しいリストに格納すると同時に元のリストから削除します。 実装コード def Nnumberele(list1, N):