diff --git a/703-Kth-Largest-Element-in-a-Stream/note.md b/703-Kth-Largest-Element-in-a-Stream/note.md
new file mode 100644
index 0000000..80cc13b
--- /dev/null
+++ b/703-Kth-Largest-Element-in-a-Stream/note.md
@@ -0,0 +1,33 @@
+# 703. Kth Largest Element in a Stream
+
+
+
+## step1(まず通す)
+
+ヒープを書くのに自信がなかったので、最初にソートしてあとは2分探索で挿入してくコードを書いた。
+ヒープは書こうとしてとしてめちゃくちゃ時間をかけてしまった。非常に混乱しながら書いているのでとても効率の悪いコードになっている。時間がもったいないのでもっと早く他の人のコードを読みにいくべきだった。
+
+## step2(整形&他の人のコードを読む)
+
+- そもそも insert している時点で挿入部分の時間計算量が配列の長さnに対して O(n) あるので2分探索じゃなくていっそ線形に探索した方が楽だった
+- heapq というライブラリがあるのでそれを使えば話が早そうではある
+ -
+- みなさん、max ヒープを作って k 回 pop するんじゃなくて、k 要素の min ヒープを作っていらっしゃる
+ - など
+ - 「k番目に大きい=大きい方からk要素だけの中で最小」なので、こうすると判定が早い
+- 簡単にセルフ実装してみた。最初 push を↓のように書いていて時間計算量がO(配列長さ) だなあと思っていたところ CPython では 末尾を pop してから先頭をその値で上書きしていた。なるほどいいやり方だ。
+ -
+- 親の位置をビット演算で計算しているのも勉強になる
+ -
+- 最初書いた時はクラスのメンバ変数として Minheap.heap を持たせたために self.heap を直接いじるメソッドと引数として受け取るメソッドが混在していたので改善した
+ - CPython の heapq は関数を集めた名前空間
+
+```python
+ def pop(self) -> int:
+ head = self.heap[0]
+ # 配列をスライスしているので O(k) かかるがそれで良いのかと思ったが
+ self.heap = self.heapify(self.heap[1:])
+ return head
+```
+
+## step3(10分以内にさっとかける * 3回)
diff --git a/703-Kth-Largest-Element-in-a-Stream/step1.py b/703-Kth-Largest-Element-in-a-Stream/step1.py
new file mode 100644
index 0000000..90635b2
--- /dev/null
+++ b/703-Kth-Largest-Element-in-a-Stream/step1.py
@@ -0,0 +1,24 @@
+from typing import List
+
+
+class KthLargest:
+ def __init__(self, k: int, nums: List[int]):
+ self.k = k
+ self.descending_nums = sorted(nums, reverse=True)
+
+ def add(self, val: int) -> int:
+ expanded_nums = [float("inf")] + self.descending_nums + [float("-inf")]
+ interval_head = 0
+ interval_tail = len(expanded_nums) - 1
+ interval_center = (interval_tail + interval_head) // 2
+ while interval_head != interval_tail:
+ if val >= expanded_nums[interval_center]:
+ interval_tail = interval_center
+ interval_center = (interval_tail + interval_head) // 2
+ else:
+ interval_head = interval_center + 1
+ interval_center = (interval_tail + interval_head) // 2
+
+ self.descending_nums.insert(interval_head - 1, val)
+
+ return self.descending_nums[self.k - 1]
diff --git a/703-Kth-Largest-Element-in-a-Stream/step1_heap.py b/703-Kth-Largest-Element-in-a-Stream/step1_heap.py
new file mode 100644
index 0000000..9d4ab83
--- /dev/null
+++ b/703-Kth-Largest-Element-in-a-Stream/step1_heap.py
@@ -0,0 +1,41 @@
+from typing import List
+
+
+class KthLargest:
+ def __init__(self, k: int, nums: List[int]):
+ self.k = k
+ self.max_heap_nums = self.max_heapify(nums)
+
+ def max_heapify_root(self, nums: List[int], parent: int, tail: int):
+ while True:
+ left_child = parent * 2 + 1
+ right_child = (parent + 1) * 2
+ largest = parent
+ if left_child <= tail and nums[largest] < nums[left_child]:
+ largest = left_child
+ if right_child <= tail and nums[largest] < nums[right_child]:
+ largest = right_child
+
+ if largest != parent:
+ nums[parent], nums[largest] = nums[largest], nums[parent]
+ parent = largest
+ else:
+ return
+
+ def max_heapify(self, nums: List[int]):
+
+ tail = len(nums) - 1
+ for parent in range(len(nums) // 2, -1, -1):
+ self.max_heapify_root(nums, parent, tail)
+
+ return nums
+
+ def add(self, val: int) -> int:
+ self.max_heap_nums = [val] + self.max_heap_nums
+ self.max_heapify_root(self.max_heap_nums, 0, len(self.max_heap_nums) - 1)
+ rest = self.max_heap_nums
+ for _ in range(self.k):
+ rest_largest = rest[0]
+ rest = self.max_heapify(rest[1:])
+
+ return rest_largest
diff --git a/703-Kth-Largest-Element-in-a-Stream/step2.py b/703-Kth-Largest-Element-in-a-Stream/step2.py
new file mode 100644
index 0000000..e15009d
--- /dev/null
+++ b/703-Kth-Largest-Element-in-a-Stream/step2.py
@@ -0,0 +1,74 @@
+from typing import List
+
+
+class KthLargest:
+ def __init__(self, k: int, nums: List[int]):
+ self.k = k
+ self.k_largest_elements = self.heapify(nums)
+
+ def add(self, val: int) -> int:
+ self.push(self.k_largest_elements, val)
+ return self.k_largest_elements[0]
+
+ def _parent(self, child: int) -> int:
+ return (child - 1) // 2
+
+ def _left_child(self, parent: int) -> int:
+ return parent * 2 + 1
+
+ def _right_child(self, parent: int) -> int:
+ return (parent + 1) * 2
+
+ def _shift_up(self, heap: List[int], index: int):
+ while index > 0 and heap[index] < heap[self._parent(index)]:
+ heap[index], heap[self._parent(index)] = (
+ heap[self._parent(index)],
+ heap[index],
+ )
+ index = self._parent(index)
+
+ def _shift_down(self, heap: List[int], index: int):
+ heap_size = len(heap)
+ while True:
+ smallest = index
+ if (
+ self._left_child(index) < heap_size
+ and heap[self._left_child(index)] < heap[smallest]
+ ):
+ smallest = self._left_child(index)
+ if (
+ self._right_child(index) < heap_size
+ and heap[self._right_child(index)] < heap[smallest]
+ ):
+ smallest = self._right_child(index)
+
+ if smallest == index:
+ break
+ heap[index], heap[smallest] = (
+ heap[smallest],
+ heap[index],
+ )
+ index = smallest
+
+ def push(self, heap: List[int], num: int):
+ heap_size = len(heap)
+ if heap_size < self.k:
+ heap.append(num)
+ self._shift_up(heap, len(heap) - 1)
+ elif num > heap[0]:
+ heap[0] = num
+ self._shift_down(heap, 0)
+
+ def pop(self, heap: List[int]) -> int:
+ head = heap[0]
+ tail = heap.pop()
+ if heap:
+ heap[0] = tail
+ self._shift_down(heap, 0)
+ return head
+
+ def heapify(self, nums: List[int]) -> List[int]:
+ heap: List[int] = []
+ for index in range(len(nums)):
+ self.push(heap, nums[index])
+ return heap
diff --git a/703-Kth-Largest-Element-in-a-Stream/step3.py b/703-Kth-Largest-Element-in-a-Stream/step3.py
new file mode 100644
index 0000000..f8539e1
--- /dev/null
+++ b/703-Kth-Largest-Element-in-a-Stream/step3.py
@@ -0,0 +1,17 @@
+from typing import List
+import heapq
+
+
+class KthLargest:
+ def __init__(self, k: int, nums: List[int]):
+ self.k = k
+ self.k_largest_elements = []
+ for num in nums:
+ self.add(num)
+
+ def add(self, val: int) -> int:
+ if len(self.k_largest_elements) < self.k:
+ heapq.heappush(self.k_largest_elements, val)
+ elif val > self.k_largest_elements[0]:
+ heapq.heappushpop(self.k_largest_elements, val)
+ return self.k_largest_elements[0]