-
Notifications
You must be signed in to change notification settings - Fork 0
【Grind75Hard】3問目42. Trapping Rain Water #63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # brute force | ||
| # 現在地より左側の最大値が左の壁、右側の最大値が右の壁となる。 | ||
| # 現在地の水位は、左右の壁の小さいほうになる。 | ||
| # 現在地が壁より低ければ、水が貯まる。 | ||
| # O(n^2) | ||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| total_water = 0 | ||
| for i in range(1, len(height) - 1): # 両端には水が貯まらないので除外 | ||
| left_wall = max(height[:i]) | ||
| right_wall = max(height[i + 1 :]) | ||
| water_height = min(left_wall, right_wall) | ||
| if water_height < height[i]: | ||
| continue | ||
| total_water += water_height - height[i] | ||
| return total_water | ||
|
|
||
|
|
||
| # stackを使って実装 | ||
| # 左側の壁をstackで記憶し、右側の壁が見つかったら、貯まる水を計算する。 | ||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| left_walls = [] | ||
| total_water = 0 | ||
| for right in range(len(height)): | ||
| while left_walls and height[left_walls[-1]] <= height[right]: | ||
| bottom_index = left_walls.pop() | ||
| if not left_walls: | ||
| break | ||
| left = left_walls[-1] | ||
| distance = right - left - 1 | ||
| depth = min(height[left], height[right]) - height[bottom_index] | ||
| total_water += distance * depth | ||
| left_walls.append(right) | ||
| return total_water | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| # DPを使って解く | ||
| # brute forceと同じ考え方だが、左右の壁の最大値を記憶しておく | ||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| max_left = [0] * len(height) # [0,i]の範囲の最大値 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. うまく命名できていないと思っていたので、ありがたいです。 |
||
| max_right = [0] * len(height) # [i,length)の範囲の最大値 | ||
| max_left[0] = height[0] | ||
| max_right[-1] = height[-1] | ||
| for i in range(1, len(height)): | ||
| max_left[i] = max(max_left[i - 1], height[i]) | ||
| max_right[-i - 1] = max(max_right[-i], height[-i - 1]) | ||
| total_water = 0 | ||
| for i in range(1, len(height) - 1): | ||
| water_height = min(max_left[i], max_right[i]) | ||
| total_water += water_height - height[i] | ||
| return total_water | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| max_left = [0] * len(height) | ||
| max_right = [0] * len(height) | ||
| max_left[0] = height[0] | ||
| max_right[-1] = height[-1] | ||
| for i in range(1, len(height)): | ||
| max_left[i] = max(max_left[i - 1], height[i]) | ||
| max_right[-i - 1] = max(max_right[-i], height[-i - 1]) | ||
| total_water = 0 | ||
| for i in range(1, len(height) - 1): | ||
| water_height = min(max_left[i], max_right[i]) | ||
| total_water += water_height - height[i] | ||
| return total_water |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # DPを使って解く | ||
| # 変数名を修正 | ||
| # max_height_in_rightはmax_heights_in_leftとは別のループで構築する | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
これ、私が推奨した変数名ですね…。申し訳ないです…。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right側だけheightが複数形になってませんでした。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. いえいえ、変数名は複数形でも単数形でも良さそうなのですが、統一した方が良さそうですよね。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. height と heights の違い、見落としておりました。 nice catch です。 |
||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| max_heights_in_left = [0] * len(height) # [0,i]の範囲の最大値 | ||
| max_height_in_right = [0] * len(height) # [i,length)の範囲の最大値 | ||
| max_heights_in_left[0] = height[0] | ||
| max_height_in_right[-1] = height[-1] | ||
| for i in range(1, len(height)): | ||
| max_heights_in_left[i] = max(max_heights_in_left[i - 1], height[i]) | ||
| for i in range(len(height) - 2, -1, -1): | ||
| max_height_in_right[i] = max(max_height_in_right[i + 1], height[i]) | ||
| total_water = 0 | ||
| for i in range(1, len(height) - 1): | ||
| water_height = min(max_heights_in_left[i], max_height_in_right[i]) | ||
| total_water += water_height - height[i] | ||
| return total_water | ||
|
|
||
|
|
||
| # stackを使って実装 | ||
| # 変数名を修正 | ||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| left_wall_indexes = [] | ||
| total_water = 0 | ||
| for right in range(len(height)): | ||
| while left_wall_indexes and height[left_wall_indexes[-1]] <= height[right]: | ||
| bottom_index = left_wall_indexes.pop() | ||
| if not left_wall_indexes: | ||
| break | ||
| left = left_wall_indexes[-1] | ||
| distance = right - left - 1 | ||
| depth = min(height[left], height[right]) - height[bottom_index] | ||
| total_water += distance * depth | ||
| left_wall_indexes.append(right) | ||
| return total_water | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Space: O(1) | ||
| # 左右からポインタをずらしていく | ||
| # 片方のポインタは今までの最大値で止まるようにしておく | ||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| left_max = 0 | ||
| right_max = 0 | ||
| left = 0 | ||
| right = len(height) - 1 | ||
| total_water = 0 | ||
| while left < right: | ||
| if height[left] < height[right]: | ||
| left_max = max(left_max, height[left]) | ||
| total_water += left_max - height[left] | ||
| left += 1 | ||
| else: | ||
| right_max = max(right_max, height[right]) | ||
| total_water += right_max - height[right] | ||
| right -= 1 | ||
| return total_water | ||
|
|
||
|
|
||
| # DPを使って解く | ||
| # 変数名を修正 | ||
| class Solution: | ||
| def trap(self, height: List[int]) -> int: | ||
| max_heights_in_left = [0] * len(height) # [0,i]の範囲の最大値 | ||
| max_heights_in_right = [0] * len(height) # [i,length)の範囲の最大値 | ||
| max_heights_in_left[0] = height[0] | ||
| max_heights_in_right[-1] = height[-1] | ||
| for i in range(1, len(height)): | ||
| max_heights_in_left[i] = max(max_heights_in_left[i - 1], height[i]) | ||
| for i in range(len(height) - 2, -1, -1): | ||
| max_heights_in_right[i] = max(max_heights_in_right[i + 1], height[i]) | ||
| total_water = 0 | ||
| for i in range(1, len(height) - 1): | ||
| water_height = min(max_heights_in_left[i], max_heights_in_right[i]) | ||
| total_water += water_height - height[i] | ||
| return total_water |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
変数名
left_wallsですと、中にどのような値が含まれているのか分かりませんでした。left_wall_indexes等、インデックスが含まれていることを表す変数名のほうが良いと思います。