From 991655bbb5a07f7c508494233b6b22494d5517df Mon Sep 17 00:00:00 2001 From: haniwachan Date: Fri, 8 Nov 2024 05:52:25 -0800 Subject: [PATCH 1/4] =?UTF-8?q?703=5FKth=5FLargest=5FElement=5Fin=5Fa=5Fst?= =?UTF-8?q?ream=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../703_Kth_Largest_Element_in_a_stream.md | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md diff --git a/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md new file mode 100644 index 0000000..90f033a --- /dev/null +++ b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md @@ -0,0 +1,156 @@ +<問題> +https://leetcode.com/problems/kth-largest-element-in-a-stream/description/ + +# step1 + +5分程度答えを見ずに考えて、手が止まるまでやってみる。 +何も思いつかなければ、答えを見て解く。 +ただし、コードを書くときは答えを見ないこと。 +正解したら一旦OK。 +思考過程もメモしてみる。 + +```c++ +class KthLargest { +public: + + vector scores; + int kth; + + KthLargest(int k, vector& nums) { + scores=nums; + sort(scores.rbegin(),scores.rend()); + kth=k; + } + + int add(int val) { + scores.push_back(val); + sort(scores.rbegin(),scores.rend()); + if((int)size(scores)>kth){ + return scores[kth-1]; + }else{ + return scores[kth-1]; + } + } +}; + +/** + * Your KthLargest object will be instantiated and called as such: + * KthLargest* obj = new KthLargest(k, nums); + * int param_1 = obj->add(val); + */ +``` + +【考えたこと】 +- k番目を取り出すとのことなどで、要素くわえるごとにソートすればいいと思った。 +- classのメンバ変数とメンバ関数、外部の関数との変数などのやりとりに慣れておらず、変数をpublicに用意しないといけないことなど少し戸惑う。もっとclassになれないといけない。 +- k番目の値がないときは場合分けした。(想定しない値が入ったときの例外処理を書くことが自然にできないので、練習が必要。 +- はじめのsortでO(NlogN)、追加ごとにO(n)をクエリk回分だけ実施する。 + +# step2 +他の方が描いたコードを見て、参考にしてコードを書き直してみる。 +参考にしたコードのリンクは貼っておく。 +読みやすいことを意識する。 +他の解法も考えみる。 + +計算量:O(N) +N:sの文字サイズ + +```c++ +class KthLargest { +public: + + map canditates; + int kth; + + KthLargest(int k, vector& nums) { + for(int i=0;isecond==1){ + canditates.erase(canditates.begin()); + }else{ + canditates.begin()->second--; + } + } + + kth=k; + } + + int add(int val) { + if(canditates.count(val)!=0){ + canditates[val]++; + }else{ + canditates[val]=1; + } + + if(canditates.begin()->second==1){ + canditates.erase(canditates.begin()); + }else{ + canditates.begin()->second--; + } + + auto iter=canditates.begin(); + int ans= iter->first; + return ans; + } +}; + +/** + * Your KthLargest object will be instantiated and called as such: + * KthLargest* obj = new KthLargest(k, nums); + * int param_1 = obj->add(val); + */ +``` + +まず(大きほうから)k番目以降を保持する必要がない。 +すなわち、k個のデータ構造に1個追加されたときに、 +一番小さいものを削除すればよい→min heapを使える。 +https://github.com/doocs/leetcode/blob/main/solution/0700-0799/0703.Kth%20Largest%20Element%20in%20a%20Stream/README_EN.md + +priority queueは一度実装しておいたほうがよい。 +https://discord.com/channels/1084280443945353267/1192736784354918470/1194613857046503444 + +priority queueの前にmapを使った実装を考えるべき +step2ではmapをつかって実装したが、いまいちわかりにくいコードな気がする。 +mapのキーを与えられた値として、値の個数を管理する。 +mapはk個の値を持つ。 + +https://discord.com/channels/1084280443945353267/1183683738635346001/1185264362508795984 +https://discord.com/channels/1084280443945353267/1200089668901937312/1202182322229882920 + +重複ありのmapもある +https://cpprefjp.github.io/reference/map/multimap.html + +C++はmapが平衡2分木 +https://pyteyon.hatenablog.com/entry/2019/01/01/220850#map-%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A02%E5%88%86%E6%9C%A8 + + +選択肢が見えなさすぎる感じがする。 +一つ見つけたら、思考停止してしまう。 + +- 参考 + +https://github.com/kazukiii/leetcode/pull/9/files +https://github.com/cheeseNA/leetcode/pull/12/files +https://github.com/TORUS0818/leetcode/pull/10/files +https://github.com/nittoco/leetcode/pull/11/files +https://github.com/Ryotaro25/leetcode_first60/pull/9/files +https://github.com/goto-untrapped/Arai60/pull/23/files + +# step3 + +今度は、時間を測りながら、もう一回、書きましょう。書いてアクセプトされたら文字消してもう一回書く。これを10分以内に一回もエラーを出さずに書ける状態になるまで続ける。3回続けてそれができたらその問題はOK。 + +実施しました。 \ No newline at end of file From 16cb7a20b8aaaaeb484dc78a5db8875cb95f5463 Mon Sep 17 00:00:00 2001 From: haniwachan Date: Sat, 9 Nov 2024 23:30:32 -0800 Subject: [PATCH 2/4] =?UTF-8?q?=EF=BC=83step4=E3=81=A8=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../703_Kth_Largest_Element_in_a_stream.md | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md index 90f033a..b707a66 100644 --- a/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md +++ b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md @@ -153,4 +153,47 @@ https://github.com/goto-untrapped/Arai60/pull/23/files 今度は、時間を測りながら、もう一回、書きましょう。書いてアクセプトされたら文字消してもう一回書く。これを10分以内に一回もエラーを出さずに書ける状態になるまで続ける。3回続けてそれができたらその問題はOK。 -実施しました。 \ No newline at end of file +実施しました。 + +# step4 + +レビューを受けて、コードを修正する。 +再度3回連続acceptされるまで続ける。 + +```c++ +class KthLargest { +private: + map canditates; + int kth; + +public: + KthLargest(int k, vector& nums) { + kth=k; + + for (int i=0; isecond--; + if (canditates.begin()->second<=0) { + canditates.erase(canditates.begin()); + } + } + } + int add(int val) { + canditates[val]++; + canditates.begin()->second--; + if (canditates.begin()->second<=0) { + canditates.erase(canditates.begin()); + } + return canditates.begin()->first; + } +}; + +/** + * Your KthLargest object will be instantiated and called as such: + * KthLargest* obj = new KthLargest(k, nums); + * int param_1 = obj->add(val); + */ +``` \ No newline at end of file From 7cec97873bb633289c7a76dad6cac50ec5694b41 Mon Sep 17 00:00:00 2001 From: haniwachan Date: Sun, 10 Nov 2024 08:04:52 -0800 Subject: [PATCH 3/4] =?UTF-8?q?step4=5F2=20=E9=96=A2=E6=95=B0=E3=81=AB?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92=E3=81=BE=E3=81=A8=E3=82=81=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../703_Kth_Largest_Element_in_a_stream.md | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md index b707a66..d6ab503 100644 --- a/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md +++ b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md @@ -155,7 +155,7 @@ https://github.com/goto-untrapped/Arai60/pull/23/files 実施しました。 -# step4 +# step4_1 レビューを受けて、コードを修正する。 再度3回連続acceptされるまで続ける。 @@ -196,4 +196,33 @@ public: * KthLargest* obj = new KthLargest(k, nums); * int param_1 = obj->add(val); */ +``` + +# step4_2 +関数に処理をまとめました。 + +```C++ +class KthLargest { +private: + map candidates; + int kth; + void add_num_to_candidates(int nums_add){ + candidates[nums_add]++; + candidates.begin()->second--; + if (candidates.begin()->second<=0) { + candidates.erase(candidates.begin()); + } + } +public: + KthLargest(int k, vector& nums) { + kth=k; + + for (int i=0; ifirst; + } +}; ``` \ No newline at end of file From 72cb2942ebfee683e9e299ca496e23668f57e47d Mon Sep 17 00:00:00 2001 From: haniwachan Date: Sun, 10 Nov 2024 09:12:35 -0800 Subject: [PATCH 4/4] =?UTF-8?q?step4=5F3=20=E5=88=9D=E6=9C=9F=E9=85=8D?= =?UTF-8?q?=E5=88=97=E7=A9=BA=E3=81=AE=E6=99=82=E3=81=AE=E5=AF=BE=E5=87=A6?= =?UTF-8?q?=E3=80=81=E9=85=8D=E5=88=97=E8=A6=81=E7=B4=A0=E6=95=B0=E3=81=8C?= =?UTF-8?q?kth=E4=BB=A5=E4=B8=8B=E3=81=AE=E6=99=82=E3=81=AE=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../703_Kth_Largest_Element_in_a_stream.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md index d6ab503..dad09c9 100644 --- a/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md +++ b/03_Heap,PriorityQueue/703_Kth_Largest_Element_in_a_stream.md @@ -225,4 +225,40 @@ public: return candidates.begin()->first; } }; +``` + +# step4_3 +・初期配列が空の時を対処。 +・配列がkth以下の時は削除処理をしないように修正。 +```c++ +class KthLargest { +private: + map candidates; + int candidates_counter=0; + int kth; + void add_num_to_candidates(int nums_add){ + candidates[nums_add]++; + candidates_counter++; + if (candidates_counter>kth) { + candidates.begin()->second--; + if (candidates.begin()->second<=0) { + candidates.erase(candidates.begin()); + } + } + } +public: + KthLargest(int k, vector& nums) { + kth=k; + + for (int i=0; ifirst; + } +}; ``` \ No newline at end of file