-
Notifications
You must be signed in to change notification settings - Fork 0
Solved: 276. Paint Fence #30
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?
Conversation
| return k | ||
| if index == 2: | ||
| return k * k | ||
| ways = cache.get(n) |
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.
PRしてから気づきましたが、ここways = cache.get(index)の間違いです。
| prev_prev_num_ways = k | ||
| prev_num_ways = k * k | ||
| num_ways = 0 | ||
| loop_count = 1 |
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.
変数に格納される値を表す編す名を付けるとよいと思いました。 fench_index などはいかがでしょうか?ただし、変数名と実際に格納される値を一致されるため、値を 2 から始め、終了条件を変えたほうがよいかもしれません。
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.
レビューありがとうございます。
おっしゃる通り、意味のあるループ用の変数を使うべきでした。
以下のようになりますね。
class Solution:
def numWays(self, n: int, k: int) -> int:
if n == 1:
return k
if n == 2:
return k * k
prev_prev_num_ways = k
prev_num_ways = k * k
num_ways = 0
fence_index = 2
while fence_index < n:
num_ways = (k - 1) * (prev_prev_num_ways + prev_num_ways)
prev_prev_num_ways = prev_num_ways
prev_num_ways = num_ways
fence_index += 1
return num_ways| prev_ways = k * k | ||
| ways = k * k | ||
| for _ in range(2, n): | ||
| ways = (k - 1) * prev_prev_ways + (k - 1) * prev_ways |
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.
少し冗長な気がするので以下のような、書き方でもいいかなと思いました。
(k - 1) * (prev_prev_ways + prev_ways)
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.
レビューありがとうございます。
意図としては、あえて式をまとめずに書いたほうが、
「前の色と違う色で塗るパターンと前の色と同じ色で塗るパターンの和を出しているのだ」という意図が伝わりやすいだろうといった具合です。
一方で、ご指摘の通り式をまとめたうえで、式の背景をコメントで残す方が適切な気がしてきました。
| return k | ||
| prev_prev_ways = k | ||
| prev_ways = k * k | ||
| ways = k * k |
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.
ここはループ内ですぐに上書きされてしまうので、n == 2 の早期returnを加えた上で削ってもいいかもしれません。
| - データを末尾に追加 | ||
|
|
||
| ということ。 | ||
| データ構造は、Doubly-Linked List or OrderedDict を使う方針がありそう。 |
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.
これ、OrderedDict の中身は Doubly-Linked List なので、まあ、練習としては、Doubly-Linked List 自体を書いて欲しいところではありますね。
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.
コメントありがとうございます。
これ、OrderedDict の中身は Doubly-Linked List なので、
おっしゃる通りでした。。
https://github.com/python/cpython/blob/main/Lib/collections/__init__.py#L89
まあ、練習としては、Doubly-Linked List 自体を書いて欲しいところではありますね。
そうですよね。練習します。
| と整理できるので、動的計画法を用いて求められる。 | ||
| 時間計算量は1~n番目まで順番に更新していくので、O(n)。空間計算量も1~n番目用に箱を作るのでO(n)。 | ||
|
|
||
| 動的計画法用の配列名って`dp`で問題ないのだろうか。一旦、`ways_is_same_before`あたりにしておく。 |
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.
動的計画法用の配列名って
dpで問題ないのだろうか。
何が入っているか明示的にわかる変数名が良いと思います。
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.
コメントありがとうございます。
ですよね。
この練習会の感覚だと何が入っているか分かる命名が良いだろうと判断しましたが、
検索してみるとdpと付けている例が多かったので揺らぎました。
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.
https://discord.com/channels/1084280443945353267/1217439924333187244/1310104727257874432
上から読んでいくと何が入っているか分からないですね。
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.
以前、dpという選択肢が浮かんだ際の感情はこんな感じでした。
https://github.com/olsen-blue/Arai60/pull/31/files#diff-b7fbb0dce1473afc0264185268f1a1ef6d682a3a8c997d43bc8bdd636a66ce4aR7
| prev_num_ways = k * k | ||
| num_ways = 0 | ||
| loop_count = 1 | ||
| while 2 + loop_count <= n: |
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.
おそらく時系列順で、数えたカウントを並べているのだと思うのですが、パッと見2という定数が先に来ているのは、見慣れない感覚がありました。
条件式は、if (変数) < (定数): みたいな形で書くのが個人的には好みです。
思考の中心にあるものを先に書いて、それを評価する、という流れが自然言語的にはしっくりくる気がしました。
例えば、天気予報見てるとして、「今日の気温は・・・20度か、もう春用の服で良いかもな。」みたいなイメージですかね。
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.
これに限らずですが、基本的に、主役を最も優先・主張して書きたい、みたいな気持ちが個人的にはあります。
ichika0615/arai60#17 (comment)
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.
主役を最も優先・主張して書きたい
かなり腑に落ちました。ありがとうございます。
自分は a < bのように右に大きいものがくるといった流れで書きたい癖があるのかなとも思いました。
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.
右に大きいものがくるといった流れで書きたい
そうですね。これは同意できます。
https://github.com/Mike0121/LeetCode/pull/50/files#diff-43981f79e9645568541fbbe2e5cbe8f3e8f41c1f5c09f3fc70b454be886545caR65
Mike0121/LeetCode#50 (comment)
| def numWays(self, n: int, k: int) -> int: | ||
| """Using 1-index""" | ||
| @cache | ||
| def get_ways(index: int): |
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.
getと表現すると、すでにあるものを取得するみたいなイメージが近いかもしれないと感じました。
https://leetcode.com/problems/paint-fence/description/
問題文
You are painting a fence of n posts with k different colors. You must paint the posts following these rules:
Every post must be painted exactly one color.
There cannot be three or more consecutive posts with the same color.
Given the two integers n and k, return the number of ways you can paint the fence.
Example 1:
Input: n = 3, k = 2
Output: 6
Explanation: All the possibilities are shown.
Note that painting all the posts red or all the posts green is invalid because there cannot be three posts in a row with the same color.
Example 2:
Input: n = 1, k = 1
Output: 1
Example 3:
Input: n = 7, k = 2
Output: 42
Constraints:
1 <= n <= 50
1 <= k <= 10^5
The testcases are generated such that the answer is in the range [0, 2^31 - 1] for the given n and k.