-
Notifications
You must be signed in to change notification settings - Fork 0
514. Paint Fence #11
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
Open
atmaxstar
wants to merge
2
commits into
main
Choose a base branch
from
514
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
514. Paint Fence #11
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| Amazon SDE1のOnline Assessmentを受けてみたが2問目のDynamic Programmingを使うHardレベルの問題が解けなかった...これまで3回Online Assessmentを受けてきたがどれもDP問題で失敗している気がする、、、動的計画法の考え方のコツを掴むために重点的にやっていきたい。 | ||
|
|
||
| ## step1: | ||
| まず1つのポストを色塗りする方法はk種類ある。なので3連続した色を塗ってはならないという制約なしで考えてみると、k種類の絵の具でn個のポストを塗る方法はk^n通り存在する。バックトラックで全通りを探索し、1個前と2個前のポストでどんな色で塗られたかを渡していき、もし塗ろうとしている色とそれらが一致している場合はスキップするという手法をとれば制約内で全ての通りを探索できそうである。早速これを実装してみる。色0、色1、、、色k-1として塗っていく。 | ||
| ### code | ||
| ```Python | ||
| class Solution: | ||
| def num_ways(self, n: int, k: int) -> int: | ||
| num_of_ways = 0 | ||
| def _count_ways(i, color_before, color_before_before): | ||
| nonlocal num_of_ways | ||
| if i == n: | ||
| num_of_ways += 1 | ||
| return | ||
| for color in range(k): | ||
| if color_before == color_before_before == color: | ||
| continue | ||
| _count_ways(i + 1, color, color_before) | ||
|
|
||
| _count_ways(0, -1, -1) | ||
|
|
||
| return num_of_ways | ||
| ``` | ||
|
|
||
| この解法はO(k^n)であり、nかkの数が大きいときは避けたい解法である。なので次は動的計画法を用いた解法を考えていきたい。 | ||
| 全くわからなかったのでGeeksForGeeksの解法をみてみる。 | ||
| まずi個までのポストでの3つ以上同じ色が並ばない塗り方の通りをnum_of_ways[i]と定義する。すると、num_of_ways[i-1]の最後のポストの色と違う色を置く通り(num_of_ways[i-1]*(k-1))と、num_of_ways[i-2]の最後のポストの色と違う色を2つ連続でおく通り(num_of_ways[i-2]*(k-1))を足したものとなる。これをコードにしていく。 | ||
|
|
||
| ```Python | ||
| class Solution: | ||
| def countWays(self,n,k): | ||
| if n == 1: | ||
| return k | ||
|
|
||
| num_of_ways = [0]*n | ||
|
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. 配列の時だとそのクセが抜けておりました... |
||
| num_of_ways[0] = k | ||
| num_of_ways[1] = k * k | ||
| for i in range(2, n): | ||
| num_of_ways[i] = (k-1) * num_of_ways[i-1] + (k-1) * num_of_ways[i-2] | ||
|
|
||
| return num_of_ways[n - 1] | ||
| ``` | ||
| 空間計算量はO(N), 時間計算量はO(N)である。 | ||
| 他にも解法を見てみたが、prev1, prev2に一個前と二個前の答えを置いておくことで空間計算量をO(1)に抑えることができるものもあった。 | ||
|
|
||
| ```Python | ||
| def countWays(n, k): | ||
|
|
||
| # base cases | ||
| if n == 1: | ||
| return k | ||
| if n == 2: | ||
| return k * k | ||
|
|
||
| # Fill value for 1 and 2 fences | ||
| prev2 = k | ||
| prev1 = k * k | ||
|
|
||
| for i in range(3, n + 1): | ||
| curr = prev1 * (k - 1) + prev2 * (k - 1) | ||
|
|
||
| # update the values | ||
| prev2 = prev1 | ||
| prev1 = curr | ||
|
|
||
| return prev1 | ||
| ``` | ||
|
|
||
| ## step2: | ||
| 個人的には配列にi個目のポストまでの塗り方の答えを入れる方がぱっと見でなんの値を参照してるのかわかりやすいのでこっちでいく。 | ||
| ### code | ||
| ```python | ||
| class Solution: | ||
| def countWays(self,n,k): | ||
| if n == 1: | ||
| return k | ||
|
|
||
| num_of_ways = [0]*n | ||
| num_of_ways[0] = k | ||
| num_of_ways[1] = k * k | ||
| for i in range(2, n): | ||
| num_of_ways[i] = (k-1) * num_of_ways[i-1] + (k-1) * num_of_ways[i-2] | ||
|
|
||
| return num_of_ways[n - 1] | ||
| ``` | ||
|
|
||
| ## step3: | ||
| ### code | ||
| ```python | ||
| class Solution: | ||
| def countWays(self,n,k): | ||
| if n == 1: | ||
| return k | ||
| num_of_ways = [0] * n | ||
| num_of_ways[0] = k | ||
| num_of_ways[1] = k * k | ||
|
|
||
| for i in range(2, n): | ||
| num_of_ways[i] = (k - 1) * num_of_ways[i - 1] + (k - 1) * num_of_ways[i - 2] | ||
|
|
||
| return num_of_ways[n - 1] | ||
| ``` | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
こちらのコメントをご参照ください。
h-masder/Arai60#18 (comment)