Complete analysis with interactive visualizations and performance optimizations
from typing import List
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
"""
最大部分配列の和を求める(Kadane's Algorithm)
Args:
nums: 整数のリスト
Returns:
最大部分配列の和
Time Complexity: O(n)
Space Complexity: O(1)
"""
# 現在の部分配列の和を追跡
current_sum: int = nums[0]
# これまでに見つけた最大の部分配列の和
max_sum: int = nums[0]
# 配列の2番目の要素から開始
for i in range(1, len(nums)):
# 現在の要素から新しく開始するか、既存の部分配列に追加するかを選択
current_sum = max(nums[i], current_sum + nums[i])
# 最大和を更新
max_sum = max(max_sum, current_sum)
return max_sum
class SolutionFinal:
"""
LeetCode提出用の最終実装(最も効率的)
"""
def maxSubArray(self, nums: List[int]) -> int:
"""
最大部分配列の和を求める(最終最適化版)
Args:
nums: 整数のリスト (1 <= len(nums) <= 10^5, -10^4 <= nums[i] <= 10^4)
Returns:
最大部分配列の和
Time Complexity: O(n)
Space Complexity: O(1)
"""
max_sum = current_sum = nums[0]
for i in range(1, len(nums)):
# max()を避けて条件演算子を使用(パフォーマンス向上)
current_sum = current_sum + nums[i] if current_sum > 0 else nums[i]
# max()を避けてif文を使用
if current_sum > max_sum:
max_sum = current_sum
return max_sum
import sys
class Solution:
def maxSubArrayDivideConquer(self, nums: List[int]) -> int:
"""
最大部分配列の和を求める(分割統治法)
Args:
nums: 整数のリスト
Returns:
最大部分配列の和
Time Complexity: O(n log n)
Space Complexity: O(log n)
"""
def divide_conquer(left: int, right: int) -> int:
"""
分割統治法のヘルパー関数
Args:
left: 左端のインデックス
right: 右端のインデックス
Returns:
指定範囲での最大部分配列の和
"""
# ベースケース: 要素が1つの場合
if left == right:
return nums[left]
# 中点を計算
mid: int = left + (right - left) // 2
# 左半分の最大部分配列の和
left_max: int = divide_conquer(left, mid)
# 右半分の最大部分配列の和
right_max: int = divide_conquer(mid + 1, right)
# 中点をまたぐ最大部分配列の和を計算
left_sum: int = -sys.maxsize
total: int = 0
for i in range(mid, left - 1, -1):
total += nums[i]
left_sum = max(left_sum, total)
right_sum: int = -sys.maxsize
total = 0
for i in range(mid + 1, right + 1):
total += nums[i]
right_sum = max(right_sum, total)
cross_sum: int = left_sum + right_sum
# 3つの候補の中から最大値を返す
return max(left_max, right_max, cross_sum)
return divide_conquer(0, len(nums) - 1)
1. 分割 (Divide): 配列を左半分と右半分に再帰的に分割
2. 統治 (Conquer): 各部分で最大部分配列を求める
3. 結合 (Combine): 中点をまたぐ最大部分配列も計算し、3つの中から最大値を選択
class Solution:
def maxSubArrayDP(self, nums: List[int]) -> int:
"""
最大部分配列の和を求める(動的プログラミング版)
メモリ使用量は多いが理解しやすい実装
Args:
nums: 整数のリスト
Returns:
最大部分配列の和
Time Complexity: O(n)
Space Complexity: O(n)
"""
n: int = len(nums)
# dp[i]は位置iで終わる最大部分配列の和
dp: List[int] = [0] * n
dp[0] = nums[0]
max_sum: int = nums[0]
for i in range(1, n):
# 前の部分配列に追加するか、新しく開始するかを選択
dp[i] = max(nums[i], dp[i-1] + nums[i])
max_sum = max(max_sum, dp[i])
return max_sum
状態定義: dp[i] = 位置iで終わる最大部分配列の和
遷移式: dp[i] = max(nums[i], dp[i-1] + nums[i])
初期状態: dp[0] = nums[0]
答え: max(dp[0], dp[1], ..., dp[n-1])
推奨用途: LeetCode提出、コンテスト
推奨用途: 学習、実装理解、チームプロジェクト
推奨用途: アルゴリズム学習、技術面接
推奨用途: DP学習、アルゴリズム教育
# ❌ 遅い実装例
def maxSubArraySlow(nums: List[int]) -> int:
current_sum = nums[0]
max_sum = nums[0]
for i in range(1, len(nums)):
# max()関数は関数呼び出しオーバーヘッドがある
current_sum = max(nums[i], current_sum + nums[i])
max_sum = max(max_sum, current_sum)
return max_sum
# ✅ 高速実装例
def maxSubArrayFast(nums: List[int]) -> int:
max_sum = current_sum = nums[0]
for i in range(1, len(nums)):
# 条件演算子でmax()を回避
current_sum = current_sum + nums[i] if current_sum > 0 else nums[i]
# if文でmax()を回避
if current_sum > max_sum:
max_sum = current_sum
return max_sum
# 🚀 さらなる最適化テクニック
def maxSubArrayUltimate(nums: List[int]) -> int:
"""
究極の最適化版:Python特有の最適化を適用
"""
max_sum = current_sum = nums[0]
# range(1, len(nums))よりもenumerate(nums[1:], 1)の方が
# 特定の条件下で高速な場合がある
for num in nums[1:]:
current_sum = current_sum + num if current_sum > 0 else num
max_sum = max_sum if max_sum >= current_sum else current_sum
return max_sum
株式の最大利益期間を見つける問題。日次の価格変動を配列とし、最大利益を得られる期間を特定。
運動データから最も効果的な運動期間を特定。心拍数や消費カロリーの変化から最適な運動区間を分析。
デバイスのバッテリー使用量から最適化対象期間を特定。消費電力の変化パターンを分析。
時系列データの異常検知やトレンド分析。売上データやユーザー行動データの分析に応用。