-
Notifications
You must be signed in to change notification settings - Fork 0
Wanwan87 703. kth largest element in a stream #8
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| # step1 | ||
| - リストにinputとなる数値を追加していく | ||
| - リストのソートをして、小さい順なら-k番目、大きい順ならk番目を出力する | ||
| - 書いてみてエラーがいくつか出たので修正 | ||
| - コンストラクタ内でself.変数=値とすることで、値とインスタンスを紐づけて格納する。selfはインスタンス自身を指すので、インスタンスが複数あっても、値を別々に保持できる。 | ||
| - sortとsortedでソートできる。sortは元のリスト自身を並び替える、sorted(リスト)は元を変えずに新しい並び替えリストを返す。sortedだと変数が増えるのでsortを選択。 | ||
| - | ||
|
|
||
| ```python | ||
| class KthLargest: | ||
|
|
||
| def __init__(self, k: int, nums: List[int]): | ||
| self.kth = k | ||
| self.score_list = nums | ||
|
|
||
| def add(self, val: int) -> int: | ||
| self.score_list.append(val) | ||
| self.score_list.sort() | ||
| return self.score_list[-self.kth] | ||
| ``` | ||
|
|
||
|
|
||
| # step2 | ||
| - https://github.com/mura0086/arai60/pull/13#discussion_r2002989542 | ||
| - https://ensta-blog.com/python/heapq/ | ||
| - 最小ヒープ: 優先度が最小の要素が先に取り出される | ||
| - headpq.heapify リストを渡すと最小ヒープに変換される。 | ||
| - >この問題、手でやるならどうしますかね。たとえば、レールの上をボールが次々と転がってきて、大きい方から5つ持って帰りたいとします。 | ||
| - 5番目に大きい数を見たいときに、インプットが[3,2,4,7,6,5,8]だとして、4が5番目に大きい。5個保持するとして最初の5個をソートすると[2,3,4,6,7]。大きいものを保持したいので、インプットの5がきたら、[3,4,5,6,7]。8がきたら、[4,5,6,7,8]。最終的に最小値を見ると5番目に大きい4となる。 | ||
| - コメント書きつつ流れを理解 | ||
|
|
||
| ```python | ||
| class KthLargest: | ||
| def __init__(self, k: int, nums: List[int]): | ||
| self.k = k | ||
| self.top_k = nums[:k] #先頭k個を取り出す | ||
| heapq.heapify(self.top_k) #最小ヒープに変換 | ||
| for i in range(k, len(nums)): | ||
| heapq.heappushpop(self.top_k,nums[i]) #nums[i]の値をpushして最小値をpopする | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
参考までにスタイルガイドへのリンクを共有いたします。 https://google.github.io/styleguide/pyguide.html#36-whitespace
なお、このスタイルガイドは“唯一の正解”というわけではなく、数あるガイドラインの一つに過ぎません。チームによって重視される書き方や慣習も異なります。そのため、ご自身の中に基準を持ちつつも、最終的にはチームの一般的な書き方に合わせることをお勧めします。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます、意識します |
||
|
|
||
| def add(self, val: int) -> int: | ||
| heapq.heappush(self.top_k, val) #ヒープにval追加 | ||
| if len(self.top_k) > self.k: # k個よりもヒープが大きい場合 | ||
| heapq.heappop(self.top_k) #ヒープの最小の値をpopする | ||
| return self.top_k[0] #ヒープの最小値がk番目に大きい値 | ||
|
|
||
| ``` | ||
|
|
||
| # step3 | ||
|
|
||
| ```python | ||
| class KthLargest: | ||
|
|
||
| def __init__(self, k: int, nums: List[int]): | ||
| self.k = k | ||
| self.top_k = nums[:k] | ||
| heapq.heapify(self.top_k) | ||
| for i in range(k,len(nums)): | ||
| heapq.heappushpop(self.top_k,nums[i]) | ||
|
|
||
| def add(self, val: int) -> int: | ||
| heapq.heappush(self.top_k,val) | ||
| if len(self.top_k) > self.k: | ||
| heapq.heappop(self.top_k) | ||
| return self.top_k[0] | ||
| ``` | ||
| ```python | ||
| class KthLargest: | ||
|
|
||
| def __init__(self, k: int, nums: List[int]): | ||
| self.k = k | ||
| self.top_k = nums[:k] | ||
| heapq.heapify(self.top_k) | ||
| for i in range(k,len(nums)): | ||
| heapq.heappushpop(self.top_k,nums[i]) | ||
|
|
||
|
|
||
| def add(self, val: int) -> int: | ||
| heapq.heappush(self.top_k,val) | ||
| if len(self.top_k) > self.k: | ||
| heapq.heappop(self.top_k) | ||
| return self.top_k[0] | ||
|
|
||
| ``` | ||
| ```python | ||
| class KthLargest: | ||
|
|
||
| def __init__(self, k: int, nums: List[int]): | ||
| self.k = k | ||
| self.top_k = nums[:k] | ||
| heapq.heapify(self.top_k) | ||
| for i in range(k, len(nums)): | ||
| heapq.heappushpop(self.top_k,nums[i]) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. numsのk個目までとそれ以降をわけずに処理をしてもいいのかなと思いました。 例えば、add関数を使う方法があります。 def __init__(self, k: int, nums: List[int]):
self.k = k
self.top_k = []
for num in nums:
self.add(num)
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ありがとうございます、提案頂いたもののほうが読みやすい気がしますね |
||
|
|
||
| def add(self, val: int) -> int: | ||
| heapq.heappush(self.top_k,val) | ||
| if len(self.top_k) > self.k: | ||
| heapq.heappop(self.top_k) | ||
| return self.top_k[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.
コードを書く前に実行時間を見積もるとよいと思います。
こちらをご参照ください
Yuto729/leetcode#16 (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.
ありがとうございます、意識してなかったので今後考えてみます。
ソート解 O(Mnlon(n))
ヒープ解 O(M*logk)
M=10^4
n=10^4+10^4
遅い場合:10^6 [ステップ/s]
早い場合:10^7
ソート
遅い側:(10^4 * 210^4 * 14.3) /10^6 = 28.610^2
早い側:286秒
ヒープ
遅い側:(10^4 * 14.3) /10^6 = 14.310^-2
早い側:14.310^-3
結構時間変わるんですね