Conversation
| num_to_index = {} | ||
|
|
||
| for i in range(0, len(nums)): | ||
| num_to_index[nums[i]] = i |
There was a problem hiding this comment.
num_to_index のバリューは最後まで使われていないですね。
set が思いつかなかったとしたら、num_to_index[nums[i]] = None などとすると、インデックスを使わないことのシグナルになると思います。
以下は set の内部実装に関して見つけたものです。
https://stackoverflow.com/questions/3949310/how-is-set-implemented
There was a problem hiding this comment.
レビュー頂き誠にありがとうございます。
step1で解法思いつかず試行錯誤してたところで使われていない値があることに気づけていませんでした。こういった点意識して再度コーディングをしてみます!
|
|
||
| for key in num_to_index.keys(): | ||
| count = 1 | ||
| while key+1 in num_to_index: |
There was a problem hiding this comment.
算術演算子の周りにスペースを入れるかどうかは、PEP8のサンプルを見る限りどちらでもいいみたいです。ひとつのPRで混ざっていると、なにか使い分けがあるのかな?と少し注意が向くのでどちらかに統一してあるといいかもです。
https://peps.python.org/pep-0008/#other-recommendations
discord のログには次のような議論が見つかりました。他の方がどのような判断をしているかの参考までに。
見た目が窮屈になるときに開けるかどうか:https://discord.com/channels/1084280443945353267/1225849404037009609/1254109293091881052
There was a problem hiding this comment.
算術演算子周りのスペースについて別のところでもご指摘を頂いておりました。ご指摘を頂く前にやったコーディングでごちゃごちゃになってしまってたと思います。今後はスペースを空ける方向で統一しようと思います。
| class Solution { | ||
| public: | ||
| int longestConsecutive(vector<int>& nums) { | ||
| unordered_set<int>num_set(nums.begin(), nums.end()); |
There was a problem hiding this comment.
自分はC++で書いていないので詳しくは知らないのですが、set関連のデータ構造はいろいろあるようです。
Ryotaro25/leetcode_first60#14 (comment)
内部実装、各種操作の計算量がPythonと異なる点も意識が必要と思われます。
Ryotaro25/leetcode_first60#14 (comment)
上記読む限り、vector を unorderd_set に変換する操作は O(n) で実行できなさそうです。
There was a problem hiding this comment.
ハッシュセット・ハッシュテーブルへの挿入は、O(1)と考えて問題ないかと思います。
| while num+length in num_set: | ||
| length+=1 | ||
|
|
||
| longest = max(length, longest) |
There was a problem hiding this comment.
好みのところでご意見いただけること、とても参考になります。ありがとうございます!
|
|
||
| for ( auto &n: nums) { | ||
| if (!num_set.contains(n-1)) { | ||
| int length = 1; |
There was a problem hiding this comment.
nums の要素の値の元の型は、関数の引数まで読み返さないとわからないので、&n の型を int に明示して、int length と揃えてもいいのかなと思いました。
一応、nums の要素数が大きい場合に、length がオーバーフローしないかは気になりました。だいたい 2* 10^9でオーバーフローしますが、扱うデータの大きさによってはあり得る状況かなと思います。(暗黙の型変換などされるのでしょうか?)
以下、int型の取りうる範囲についての参照リンクです。
https://learn.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=msvc-170
https://en.cppreference.com/w/cpp/types/climits
| @@ -0,0 +1,14 @@ | |||
| class Solution: | |||
| def longestConsecutive(self, nums: List[int]) -> int: | |||
| num_set = set(nums) | |||
There was a problem hiding this comment.
変数名 nums_set は、自分の場合は「集合だから重複は含まれていないんだな」と一段回思考を挟むことがあります。unique_nums とかもありだと思います。
| def longestConsecutive(self, nums: List[int]) -> int: | ||
| num_set = set(nums) | ||
|
|
||
| longest_consecutive_sequence = 0 |
There was a problem hiding this comment.
変数名 longest_consecutive_sequence からは、何らかの連続そのものを想起します。
長さの最大値を保存する変数の名前としてはlongest_length, max_length あたりが良いのではないかと思います。
名前のスコープがもっと長いなら longest_consecutive_sequence_length も選択肢になるかもしれません。
(調べた限りでは、sequence に 「長さ」の意味は見つけられませんでした。
https://dictionary.cambridge.org/dictionary/english/sequence
命名に使う英単語を辞書を引いてみることは、自分もよくやっているのですがおすすめです。変数名に使う英語はそれほどパターンが多くないのでだんだん網羅されている感じがあります。)
|
|
||
| longest_consecutive_sequence = 0 | ||
|
|
||
| for num in nums: |
There was a problem hiding this comment.
すでに検討されていたなら申し訳ないのですが、step1 とstep4の時間計算量、空間計算量は見積りましたか?
| @@ -0,0 +1,13 @@ | |||
| class Solution: | |||
| def longestConsecutive(self, nums: List[int]) -> int: | |||
| nums_set = set(nums) | |||
There was a problem hiding this comment.
おまけ問題として、重複も連続として数えるとした場合にどのように変更するか考えてみるのも面白いかもです。
| unordered_set nums_set(nums.begin(), nums.end()); | ||
| int longest_consecutive_sequence = 0; | ||
|
|
||
| for ( auto num: nums_set) { |
There was a problem hiding this comment.
すでにご存知でしたら申し訳ないのですが、参照渡しをするか、コピーをするか、コピーする場合はコストがかかることを意識しているかに関して discord 上で以下のような議論がありました。ご参考までに。
C++の例:https://discord.com/channels/1084280443945353267/1237649827240742942/1251719996242002043
pythonの例:
hrkh/leetcode#2 (comment)
There was a problem hiding this comment.
これ、int の場合は大きさが32ビットで、あんまりリファレンスにする必要は感じません。コピーコストが安いからですね。
| unordered_set nums_set(nums.begin(), nums.end()); | ||
| int longest_consecutive_sequence = 0; | ||
|
|
||
| for ( auto num: nums_set) { |
There was a problem hiding this comment.
フォーマットに関して discord 内でよく引用されている印象がある google C++ style guide では、for () の () 前後にスペースを入れない書き方が推奨されていました。
https://google.github.io/styleguide/cppguide.html#Formatting_Looping_Branching
There was a problem hiding this comment.
色々なところでスペースがあったりなかったり一貫性がないのが気になりますね。普通は開きカッコの後ろにスペースを入れるなら、閉じカッコの前にも入れるかと思います。sakzkさんのコメントのようにない方が一般的かと思います。
| unordered_set nums_set(nums.begin(), nums.end()); | ||
| int longest_consecutive_sequence = 0; | ||
|
|
||
| for ( auto num: nums_set) { |
There was a problem hiding this comment.
色々なところでスペースがあったりなかったり一貫性がないのが気になりますね。普通は開きカッコの後ろにスペースを入れるなら、閉じカッコの前にも入れるかと思います。sakzkさんのコメントのようにない方が一般的かと思います。
| class Solution { | ||
| public: | ||
| int longestConsecutive(vector<int>& nums) { | ||
| unordered_set<int> num_set(nums.rbegin(), nums.rend()); |
| if (!num_set.contains(n-1)) { | ||
| int length = 1; | ||
| while (num_set.contains(n + length)) { | ||
| length += 1; |
| class Solution { | ||
| public: | ||
| int longestConsecutive(vector<int>& nums) { | ||
| unordered_set<int>num_set(nums.begin(), nums.end()); |
There was a problem hiding this comment.
ハッシュセット・ハッシュテーブルへの挿入は、O(1)と考えて問題ないかと思います。
| class Solution { | ||
| public: | ||
| int longestConsecutive(vector<int>& nums) { | ||
| unordered_set nums_set(nums.begin(), nums.end()); |
There was a problem hiding this comment.
ここだけtemplate argument deductionを使っていますが、意識してやっていますか?
| nums_set = set(nums) | ||
| longest_consecutive_sequence = 0 | ||
|
|
||
| for num in nums_set: |
There was a problem hiding this comment.
なんとなく不自然さを感じます。つまり、手でやるとして、{0, 1, 2, 3, 4, 5} だったとして、0 から確認が終わった後に 1 を確認しないじゃないですか。
|
@sakzk @liquo-rice @oda |
問題: https://leetcode.com/problems/longest-consecutive-sequence