diff --git a/63/memo.md b/63/memo.md new file mode 100644 index 0000000..48e5c19 --- /dev/null +++ b/63/memo.md @@ -0,0 +1,24 @@ +# 63. Unique Paths II + +- sol1.py: dpでかいた +- sol2.py: 初期化方法と変数名を改善 + +https://github.com/olsen-blue/Arai60/pull/34#pullrequestreview-2636297197 +> コンパイラ言語ではif文(機械語にしたときの分岐命令)って(分岐予測に失敗するとパイプラインの工程を最初からやり直さないといけないので)他の命令より時間がかかるんです +> なので、可読性の面でも速度の面でもこのfor文は分けた方がよりよいですね +>でも、Pythonはインタプリタ言語(そもそもプログラムの解釈・実行に大量に分岐命令が使われてると思う)なので速度の観点では気にするような速度差は生まれないかもしれません + +これは勉強になった。 +つまり、CやRustなどんコンパイラ言語では、分岐予測に失敗するとオーバーヘッドが発生するので、for文内のif文はなるべく分けた方が良い。 +つまり、事前に決まっている分岐(0行目or0列目など)はfor文の外で行った方が良い。 +しかし、Pythonの場合はこれを気にする必要はなさそう。 + + +https://github.com/Fuminiton/LeetCode/pull/34#discussion_r2052772608 +> [0][0]にアクセスする前に一応チェックしてもいいかもしれませんね。問題文に制約があるにせよ。 + +これはたまたまできていた + +https://algo-method.com/descriptions/78 +配るDPともらうDP +配るDPで書いた:sol3.py diff --git a/63/sol1.py b/63/sol1.py new file mode 100644 index 0000000..3c73c10 --- /dev/null +++ b/63/sol1.py @@ -0,0 +1,29 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + if not obstacleGrid or not obstacleGrid[0]: + return 0 + + num_rows, num_cols = len(obstacleGrid), len(obstacleGrid[0]) + + EMPTY = 0 + + if obstacleGrid[0][0] != EMPTY: + return 0 + + unique_paths_per_row = [1] + [0] * (num_cols - 1) + + col = 1 + while col < num_cols and obstacleGrid[0][col] == EMPTY: + unique_paths_per_row[col] = 1 + col += 1 + + for row in range(1, num_rows): + for col in range(0, num_cols): + if obstacleGrid[row][col] != EMPTY: + unique_paths_per_row[col] = 0 + continue + if col == 0: + continue + unique_paths_per_row[col] += unique_paths_per_row[col - 1] + + return unique_paths_per_row[-1] diff --git a/63/sol2.py b/63/sol2.py new file mode 100644 index 0000000..152c938 --- /dev/null +++ b/63/sol2.py @@ -0,0 +1,19 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + if not obstacleGrid or not obstacleGrid[0]: + return 0 + + n_row, n_col = len(obstacleGrid), len(obstacleGrid[0]) + + unique_paths_per_row = [0] * n_col + unique_paths_per_row[0] = 0 if obstacleGrid[0][0] else 1 + + for row in range(n_row): + for col in range(n_col): + if obstacleGrid[row][col]: + unique_paths_per_row[col] = 0 + continue + elif col > 0: + unique_paths_per_row[col] += unique_paths_per_row[col - 1] + + return unique_paths_per_row[-1] diff --git a/63/sol3.py b/63/sol3.py new file mode 100644 index 0000000..684a3dd --- /dev/null +++ b/63/sol3.py @@ -0,0 +1,30 @@ +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + if not obstacleGrid or not obstacleGrid[0]: + return 0 + + n_row, n_col = len(obstacleGrid), len(obstacleGrid[0]) + + unique_paths_per_row = [0] * n_col + unique_paths_per_row[0] = 0 if obstacleGrid[0][0] else 1 + + for row in range(n_row): + unique_paths_next_row = [0] * n_col + for col in range(n_col): + if obstacleGrid[row][col]: + unique_paths_per_row[col] = 0 + continue + + paths = unique_paths_per_row[col] + if paths == 0: + continue + + if col + 1 < n_col: + unique_paths_per_row[col + 1] += paths + if row + 1 < n_row: + unique_paths_next_row[col] += paths + + if row + 1 < n_row: + unique_paths_per_row = unique_paths_next_row + + return unique_paths_per_row[-1]