O(1) Space Complexity Algorithm - Python Implementation
m×n の整数行列が与えられたとき、要素が0の場合、その行と列の全要素を0に設定する。 この操作を in-place(元の配列を直接変更)で行う必要がある。
第一行と第一列をフラグとして活用し、追加メモリを使わずにO(1)空間計算量を実現する。 元の第一行・第一列に0があるかどうかを事前に記録し、最後に適切に処理する。
第一行と第一列に元々0が含まれているかチェックし、この情報を変数に保存する。
first_row_zero = any(matrix[0][j] == 0 for j in range(n))
first_col_zero = any(matrix[i][0] == 0 for i in range(m))
内部要素(第一行・列を除く)を走査し、0を見つけた場合、対応する第一行・列の位置に0を設定(フラグ)する。
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] == 0:
matrix[i][0] = 0 # 行フラグ
matrix[0][j] = 0 # 列フラグ
設定されたフラグを確認し、対応する行・列の内部要素を0に設定する。
for i in range(1, m):
for j in range(1, n):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
保存しておいた境界状態に基づいて、第一行・第一列を適切に0に設定する。
if first_row_zero:
for j in range(n):
matrix[0][j] = 0
if first_col_zero:
for i in range(m):
matrix[i][0] = 0
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Set Matrix Zeroes - O(1) Space Solution
Time Complexity: O(mn)
Space Complexity: O(1)
"""
if not matrix or not matrix[0]:
return
m, n = len(matrix), len(matrix[0])
# 第一行・第一列の元の状態チェック
first_row_zero = any(matrix[0][j] == 0 for j in range(n))
first_col_zero = any(matrix[i][0] == 0 for i in range(m))
# 内部要素の0を検出してフラグ設定
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] == 0:
matrix[i][0] = 0 # 行フラグ
matrix[0][j] = 0 # 列フラグ
# フラグに基づいて内部要素を0に設定
for i in range(1, m):
for j in range(1, n):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
# 第一行の処理
if first_row_zero:
for j in range(n):
matrix[0][j] = 0
# 第一列の処理
if first_col_zero:
for i in range(m):
matrix[i][0] = 0
from typing import List, Any
class Solution:
def set_zeroes_production(self, matrix: List[List[int]]) -> None:
"""
業務開発向け実装(型安全・エラーハンドリング重視)
Args:
matrix: 2D integer matrix to modify in-place
Raises:
TypeError: 入力型が不正な場合
ValueError: 入力値が制約を満たさない場合
Time Complexity: O(mn)
Space Complexity: O(1)
"""
# 入力検証
self._validate_matrix_input(matrix)
# エッジケース処理
if self._is_empty_matrix(matrix):
return
m, n = len(matrix), len(matrix[0])
try:
# 境界状態の分析
first_row_zero = any(matrix[0][j] == 0 for j in range(n))
first_col_zero = any(matrix[i][0] == 0 for i in range(m))
# フラグマーキング
for i in range(1, m):
for j in range(1, n):
if matrix[i][j] == 0:
matrix[i][0] = 0
matrix[0][j] = 0
# フラグ適用
for i in range(1, m):
for j in range(1, n):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
# 境界処理
if first_row_zero:
for j in range(n):
matrix[0][j] = 0
if first_col_zero:
for i in range(m):
matrix[i][0] = 0
except Exception as e:
raise RuntimeError(f"Algorithm execution failed: {e}") from e
def _validate_matrix_input(self, matrix: Any) -> None:
"""型安全な入力検証"""
if not isinstance(matrix, list):
raise TypeError("Matrix must be a list")
if not matrix:
return # 空行列は有効
if not isinstance(matrix[0], list):
raise TypeError("Matrix must be a 2D list")
# 矩形チェック・型チェック・制約チェック
expected_cols = len(matrix[0])
for i, row in enumerate(matrix):
if not isinstance(row, list) or len(row) != expected_cols:
raise ValueError(f"Matrix must be rectangular")
for j, element in enumerate(row):
if not isinstance(element, int):
raise TypeError(f"Element at [{i}][{j}] must be integer")
if element < -2**31 or element >= 2**31:
raise ValueError(f"Element out of 32-bit range")
def _is_empty_matrix(self, matrix: List[List[int]]) -> bool:
"""空行列判定"""
return not matrix or not matrix[0]
デモを開始するには「デモ実行」ボタンをクリックしてください。
組み込み関数
any()
や
range()
を活用してC実装の恩恵を受ける。
行優先のアクセスパターンでキャッシュ効率を最大化し、実際の実行速度を向上させる。
追加メモリを一切使わず、元の配列のみを使用してO(1)空間計算量を実現。