-
Notifications
You must be signed in to change notification settings - Fork 0
322. Coin Change #41
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?
322. Coin Change #41
Conversation
|
||
### ② | ||
|
||
再帰。inf (とかsys.maxsizeとか) を使うのは少し抵抗があるが処理が簡潔になるのもあり使った。再帰の上限には注意。 |
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.
[質問]
inf (とかsys.maxsizeとか) を使うのは少し抵抗がある
こちら、どういった感覚なのか気になります。
下記で議論されている float('inf') よりは math.inf
とは違った視点な気がしましたので・・・。
#24 (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.
感覚といいますか、infの型はfloatなのでintを返すところで使うのに違和感があるな、というのが抵抗がある理由です (というか型ヒントが -> int
になってるのは間違いですね...)
sys.maxsizeについてはリンク先のコメントと同じ理由で、それより大きな値が来うる気持ち悪さがある、という感じです。実務でもこの辺りの値を使う判断もあるでしょうし (64bit環境なら) 2**63 - 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.
inf は型が float 、sys.maxsize は最大ではないのですね。。
上限の値ってどうするのがいいのかなと思っていたので、参考になりました。
ありがとうございます。
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.
上限はamount + 1
でもよさそうですね。coinの最小の値が1なので解の最大値はamount枚になります。
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.
あ、たしかに...ありがとうございます。
### ③ | ||
|
||
非再帰のDFS。実行時間が前2つと比べて明らかに遅い (前2つが1s未満に対してこちらは4s〜6sくらい) が、理由がわからなかった... | ||
stは本当はnum_coins_and_amount_stackとかにするだろうか。 |
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.
確かに st
気になりました。
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.
良いと思います。BFSの回答もいいですね。
```py | ||
class Solution: | ||
def coinChange(self, coins: List[int], amount: int) -> int: | ||
num_coins_list = [-1] * (amount + 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.
_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.
日本語で表すと、各金額(amount)ごとに必要なコインの数、みたいな感じかなと思うので自分ならnum_needed_coins
などにします。
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.
あまり伝わる情報が増えていない気がします。
そうですよねー変数名からリストであることをもうちょい伝えたいなと思ったのですが...でも変数の使われ方を見ればリストであることは分かるので名前に反映しようとしすぎなくてもいいのかもなという気がしてきました。
def coinChange(self, coins: List[int], amount: int) -> int: | ||
num_coins_list = [-1] * (amount + 1) | ||
num_coins_list[0] = 0 | ||
for i in range(amount): |
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.
listの添字が単なるインデックス以上に金額という意味を持っているのでiよりamountとかの命名が良いかなと思います。LeetCodeだと関数シグネチャがあらかじめ決まっていてamountが引数で既に使われていますが。。
class Solution: | ||
def coinChange(self, coins: List[int], amount: int) -> int: | ||
coins = list(filter(lambda c: c <= amount, coins)) | ||
num_coins_list = [-1] * (amount + 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.
大きな数で初期化すれば、if num_coins_list[i] == -1:
の判定が消せるようになり、コードがシンプルになると思います。
|
||
### ③ | ||
|
||
非再帰のDFS。実行時間が前2つと比べて明らかに遅い (前2つが1s未満に対してこちらは4s〜6sくらい) が、理由がわからなかった... |
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.
最短経路問題で深さ優先探索をすると、無駄な探索をしてしまうと思います。これが原因だと思います。最短経路問題で、かつ枝の距離が 1 のため、 2nd のように幅優先探索を使うとよいと思います。
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.
最短経路なのでダイクストラでもいいですが、全部の距離が1だと幅優先探索になりますね。
def coinChange(self, coins: List[int], target_amount: int) -> int: | ||
coins = list(filter(lambda c: c <= target_amount, coins)) | ||
queue = deque([(0, 0)]) | ||
seen = set([0]) |
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.
seen = [False] * (target_amount + 1)
とすると、ハッシュテーブルを使わなくて済むため、少し軽くなると思います。
st = [(0, 0)] | ||
while st: | ||
num_coins, current_amount = st.pop() | ||
num_coins_list[current_amount] = min(num_coins_list[current_amount], num_coins) |
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.
st に append() するタイミングで num_coins_list[next_amount]
の更新を行い、st から取り出したタイミングで、
if num_coins_list[current_amount] != num_coins:
continue
とすると、過去に処理した状態より悪い状態に対しての処理をスキップすることができ、少し早くなるかもしれません。
https://leetcode.com/problems/coin-change/description/