322. coin change#30
Conversation
| public: | ||
| int coinChange(vector<int>& coins, int amount) { | ||
| vector<int> min_num_coins(amount + 1, INT_MAX); | ||
| vector<int> is_constructable(amount + 1, 0); // 0: not constructable, 1: constructable |
There was a problem hiding this comment.
私は std::vector<bool> として真偽値型を入れる方がわかりやすく感じます。is constructable? という質問に直接答えている感じがするからです。
There was a problem hiding this comment.
std::vector は特殊化されるため、パフォーマンスが下がる場合がある点に注意が必要だと思います。個人的には std::vector のままで良いと思います。自分は std::vector を使うことが多いです。
There was a problem hiding this comment.
std::vector<bool>の場合だけ特殊化されていて、内部のデータの扱いが異なるんですね。ご指摘いただきありがとうございます!
| class Solution { | ||
| public: | ||
| int coinChange(vector<int>& coins, int amount) { | ||
| vector<int> min_num_coins(amount + 1, INT_MAX); |
There was a problem hiding this comment.
nit: std::をつけているところとつけていないところがあり、統一されていないことが少しだけ気になりました。
実際どこのheaderにあるのか意識する、練習ではあるが業務でのコーディングとの差分を少なくする、ために
#include <vector>
class Solution {
public:
int coinChange(std::vector<int>& coins, int amount) {としても良いかもしれません。
There was a problem hiding this comment.
leetcodeでは動くけども,実務を意識して敢えてincludeするということですね.見落としていた視点なので助かります.
| } | ||
| for (int coin : coins) { | ||
| if (i + coin < min_num_coins.size()) { | ||
| min_num_coins[i + coin] = std::min(min_num_coins[i + coin], min_num_coins[i] + 1); |
There was a problem hiding this comment.
ただの感想なのですが
min_num_coins[i] = std::min(min_num_coins[i], min_num_coins[i - coin] + 1)
とする過去参照?の解法の方がよく見書ける気がします。
私は、例えばフィボナッチ数列の f(n) = f(n - 1) + f(n - 2) を脳内で考えると、5番目を計算するために4番目と3番目の結果を取ってきて...と後ろ向きに参照する方法が最初に思い浮かぶのですが、みなさんどうなのでしょうね。
There was a problem hiding this comment.
コメントありがとうございます!確かに,変数の使い方については私も気になるところですね.
自分の場合「必要になってから求める(再帰)」と「下から積み上げる(ループ)」という捉え方をしているのですが,今回だと,一旦メモ化再帰(必要になってから求める)で実装しようとして失敗したため,「では『下から積み上げる』で実装しよう」と思い積み上げていく変数の使い方をしているという可能性が高そうでした.
| is_constructable[0] = 1; | ||
| min_num_coins[0] = 0; | ||
|
|
||
| for (long long i = 0; i < min_num_coins.size(); ++i) { |
There was a problem hiding this comment.
iの代わりに(amountとの名前被りを防ぎつつ)totalなどとした方が、なんの数字なのかわかりやすいかもしれません。
There was a problem hiding this comment.
同意です。「単なるループカウンタなのに long long が必要なの?」とびっくりしました。
| class Solution { | ||
| public: | ||
| int coinChange(vector<int>& coins, int amount) { | ||
| int not_achievable = 10001; |
There was a problem hiding this comment.
個人的にはクラスに static constexpr な定数変数として定義したいです。
There was a problem hiding this comment.
ありがとうございます.
「どのインスタンスでも共通かつ変更しない定数」なのでstatic constかstatic constexprで定義したく,さらに配列のサイズなどにも用いる可能性(今後の拡張可能性)を考慮してstatic constexprで定義したい,という認識で間違いないでしょうか?
| public: | ||
| int coinChange(vector<int>& coins, int amount) { | ||
| vector<int> min_num_coins(amount + 1, INT_MAX); | ||
| vector<int> is_constructable(amount + 1, 0); // 0: not constructable, 1: constructable |
There was a problem hiding this comment.
std::vector は特殊化されるため、パフォーマンスが下がる場合がある点に注意が必要だと思います。個人的には std::vector のままで良いと思います。自分は std::vector を使うことが多いです。
| ```cpp | ||
| class Solution { | ||
| public: | ||
| int coinChange(vector<int>& coins, int amount) { |
問題:322. Coin Change