Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 126 additions & 0 deletions 703_KthLargestElementInAStream/703_KthLargestElementInAStream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# 703. Kth Largest Element in a Stream
- [Arai60](https://1kohei1.com/leetcode/)
- 問題文: [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream/description/)
- 使用言語: C++
- 次に解く問題: [347. Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/description/)

## 知識セット
### 知っていたこと
- オブジェクト指向におけるクラスとは何かの概要
- コンストラクタ
- インスタンス
- メンバ変数
- メンバ関数(メソッド)

### 今回調べたこと
- privateとpublicについて
- thisポインタの使い方
- C++における範囲for文
- C++における初期化子リスト
- 代入ではなく初期化を行う
- 効率と、constへの代入が可能なのがメリット

## Step1
- 所要時間: 30min.
- 方針: vectorを毎回sortして[k-1]番目の値を返す
- TLEしそう
- TLEしました。そりゃそう。
- コード
```cpp
class KthLargest {
public:
int k_val;
std::vector<int> scores;

KthLargest(int k, std::vector<int>& nums) {
k_val = k;
scores = nums;
}

int add(int val) {
this->scores.push_back(val);
std::sort(this->scores.rbegin(), this->scores.rend());
if (scores.size() < k_val) {
return -1;
}
return scores[this.k_val - 1];
}
};
```
- 計算量
- 時間計算量: O(N^2 logN)
- N回sortで毎回O(N logN)のsort
- nums.lengthが最大で10^4なのでTLE
- 大体O(10^9)を超えるとTLEする印象。競プロの話です
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O(109) という表記に違和感を感じます。ビッグオー表記は、計算量がパラメーター (N 等) に対して、どのような関数の形で表現されるかを表します。そのため、 O(???) の中に入る文言は、パラメーターに関する関数 (または 1) であるべきだと思います。
ビッグオー表記の中の関数にパラメーターの上限を代入すると、おおよその計算ステップ数が分かります。今回の場合は、「計算ステップ数が 109 を超えると TLE する印象」と書いたほうが伝わりやすいと思います。

また、計算ステップ数が 109 を超えると TLE する理由については、以下のコメントをご参照ください。
Yuto729/LeetCode_arai60#16 (comment)

Copy link
Owner Author

@liruly liruly Jan 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

計算ステップ数という表現があるのは存じ上げませんでした。ご指摘ありがとうございます。
また、多言語他言語の実行時間目安は知らなかったので勉強になりました。

- 空間計算量: O(N)

## Step2
- 所要時間: 10min.
- 方針: priority_queueを使用
- 要件を読み替えると、上からk件保存して最小の値を返せばいい
- 最適なデータ構造は、最小値を保持するpriority_queue
- デフォルトだと最大値を保持するので注意する
- Google Style Guideに極力準拠してみる
- コード
```cpp
class KthLargest {
public:
int k_;
std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap_;

KthLargest(int k, std::vector<int>& nums) {
k_ = k;
for (int n : nums) {
add(n);
}
}

int add(int val) {
min_heap_.push(val);
if (min_heap_.size() > k_) {
min_heap_.pop();
}
return min_heap_.top();
}
};
```
- 計算量
- 時間計算量: O(N log(N))
- priority_queueの追加・削除はO(log(N))
- 空間計算量: O(N)

## Step3
- 所要時間: 15min
- 方針: リファクタリング
- 初期化子リスト
- privateやエラーハンドリング等、防衛的プログラミング
- コード
```cpp
class KthLargest {
private:
const int k_;
std::priority_queue<int, std::vector<int>, std::greater<int>> top_k_;

public:
KthLargest(int k, vector<int>& nums) : k_(k) {
for (int n : nums) {
add(n);
}
}

int add(int val) {
top_k_.push(val);

if (top_k_.size() > k_) {
top_k_.pop();
Comment on lines +114 to +115
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この問題では必要ないですが、while文を使ってwhile (top_k_.size() > k_) のようにも書けますね。
こちらを好んでいる方もいらっしゃいました。参考

Copy link
Owner Author

@liruly liruly Jan 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。
確かにカプセル化に失敗したりで外部からデータを操作され想定以上のデータが入っていた場合の防御策にはなりますね。

ただそれをするなら、想定より値が少なかったときの処理も考えないとバランスが悪いかなと思いました。

この方式だとk+1番目以降のデータはもはや保持していないので下のコードのようにエラーを投げるしかないですが...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確かに、外部からの注入なども考えると、要素が少ない時も考慮した方が堅牢ですね。
先程のコメントについては、コードが複雑になった時にミスなく読み書きしやすい、くらいの気持ちでした。
mamo3gr/arai60#25 (comment)

} else if (top_k_.size() < k_) {
return -1;
}

return top_k_.top();
}
};
```
- 計算量
- 時間計算量: O(N log(N))
- 空間計算量: O(N)