-
Notifications
You must be signed in to change notification settings - Fork 0
703. Kth Largest Element in a Stream #23
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
class KthLargest { | ||
private final int k; | ||
private TreeMap<Integer, Integer> scores; | ||
private int scoreCount; |
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.
自分なら numScores と名付けると思います。チームの平均的な書き方に合わせることをお勧めいたします。
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.
ありがとうございます。たしかにそうですね。意識してみます。
## Step 3 | ||
|
||
今度は、時間を測りながら、もう一回書く。 | ||
アクセプトされたら消すを 3 回連続できたら問題は OK。 |
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.
step3 が一番読みやすかったです。
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.
ありがとうございます。
- > 平衡二分木が C++ だったら map があり、これは順番に並んでいます。 | ||
- 平衡二分探索木 | ||
- https://ja.wikipedia.org/wiki/%E5%B9%B3%E8%A1%A1%E4%BA%8C%E5%88%86%E6%8E%A2%E7%B4%A2%E6%9C%A8 | ||
- Java だと TreeMap がそれに当たるっぽい(赤黒木) |
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.
この問題を解いたことないところからの質問失礼します。
上記priority_queueとmapの議論も読ませてもらったのですが、問題の要求的に
1.どうやってk番目の順位のスコアを知るか
2.新しいスコアが入ってきたときの適切な更新
の2つの要求があって、1と2どちらも解決できるデータ構造としてpriority_queueとmapどっちがいいか(まずよく使われるMapを思い出してもいいのでは)という議論だと認識してます。
しかしもっと単純にもしそれらのライブラリを知らなかったら、1を求めるために最初はソートで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.
コメントありがとうございます。仰るとおりコメントいただいた解法でも問題ないと思います。
以下に追加実装してみました。
https://github.com/katsukii/leetcode/pull/23/files#diff-2cbd596e05763f14077e25b7a93421a6edb70d86913362e022332db1f0073c34R179
} else { | ||
int kthScore = scores.firstKey(); | ||
if (val > kthScore) { | ||
scores.put(val, scores.getOrDefault(val, 0) + 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.
私はこの put と getOrDefault を一行に書くのは好みではないです。
2回 val が出てきて、あと目が左右に振られますね。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.kqo7dp4vlnzh
val を2回書かないならば compute を使うようなのもありますが、素直に2行にするのも一つです。
https://discord.com/channels/1084280443945353267/1300342682769686600/1357629082069893221
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行にした方が断然わかりやすいですね。今後そうします。
} | ||
|
||
public int add(int val) { | ||
if (scores.size() < 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.
このif-else if文を読んでいて、elseのケースが大丈夫なのかなというのを考えるのに少し時間が取られたのでもう少し素直に書ける余地があるかなと思います。
とりあえずqueuに突っ込んでしまって、要素がサイズを超えていれば、減らしてあげるみたいな感じのほうがシンプルかなと個人的には思います。
public int add(int val) {
scores.offer(val);
if (scores.size() > k) {
scores.poll();
}
return scores.peek();
}
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.
たしかにこちらの方が分かりやすいです。ありがとうございます。
int kthScore = scores.firstKey(); | ||
if (val > kthScore) { | ||
scores.put(val, scores.getOrDefault(val, 0) + 1); | ||
scoreCount++; |
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.
こことL128のコードが不要ですね。ソースコードを書いていて結果的に不要になった感じですかね。
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.
完全に消し忘れです。ありがとうございます。
sortedList.add(insertPosition, val); | ||
|
||
if (sortedList.size() > k) { | ||
sortedList.remove(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.
L237でbinarySearchを使っているのは、この配列がソート済みなことを利用してO(log(k))
で要素を追加したいということなのかなと思うのですが、結局ここで配列の先頭要素を削除しているので、O(k)
になっていると思います(削除後に左詰めされるのでそこで線形に時間が掛かる)。
https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html
All of the other operations run in linear time (roughly speaking).
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.
ジャストアイデアですが、降順にソートしてあげて削除は末尾要素にすれば解決するかなと思いました。
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.
ご指摘ありがとうございます。おっしゃるとおりO(k)ですね。
降順にソートしてあげて削除は末尾要素にすれば解決するかなと思いました。
たしかに、削除の部分の時間計算量は削除がO(1)になるため平均時間計算量はマシになりますね。sortedList.add(insertPosition, val);
が相変わらずシフトするので最悪時間計算量はO(k)のままですが。
問題
https://leetcode.com/problems/kth-largest-element-in-a-stream/
言語
Java
次の問題
Top K Frequent Elements