Python 0703.py
class KthLargest:
def __init__(self, k: int, nums: List[int]):
self.k = k
self.heap = nums.copy()
heapify(self.heap)
while len(self.heap) > k:
heappop(self.heap)
def add(self, val: int) -> int:
heappush(self.heap, val)
if len(self.heap) > self.k:
heappop(self.heap)
return self.heap[0]
Difficulty
and has an acceptance rate of about 61% (1+ million submissions).
Typical patterns to solve this problem:
- Data Stream
- Design
- Heap (Priority Queue)
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation defines a class that maintains the k-th largest element of a dynamic integer collection. It leverages Python’s built-in heap utilities to keep a min-heap whose size never exceeds k. The smallest element in this heap is always the current k-th largest value, which can be returned in constant time after each insertion.
Key Steps
Initialization
def __init__(self, k: int, nums: List[int]):
self.k = k
self.heap = nums.copy()
heapify(self.heap)
while len(self.heap) > k:
heappop(self.heap)
The constructor stores the target rank k and creates a private copy of the input list. By calling heapify the list is transformed into a valid min-heap in a single linear pass. The subsequent loop repeatedly removes the smallest element until the heap size matches k. After this process the heap contains exactly the k largest values from the original collection, and its root (self.heap[0]) is the k-th largest.
Adding a Value
def add(self, val: int) -> int:
heappush(self.heap, val)
if len(self.heap) > self.k:
heappop(self.heap)
return self.heap[0]
When a new integer arrives, it is inserted into the heap with heappush. If the insertion makes the heap larger than k, the smallest element is removed with heappop. This guarantees that the heap never stores more than k items, and the root remains the current k-th largest. The method returns this root directly.
Edge Cases Handled
The code gracefully deals with an empty initial list. heapify on an empty list produces an empty heap, and the trimming loop does not execute because the length is already zero. Subsequent calls to add will populate the heap up to size k without any special-case logic.
When k equals one, the heap is reduced to a single element after initialization. Each call to add pushes the new value and immediately discards the smaller of the two, leaving the maximum value at the root. This behavior correctly yields the largest element at all times.
If the initial list contains fewer than k elements, the trimming loop never runs, leaving the heap size equal to the number of supplied values. The add method then grows the heap until it reaches k, after which the size-capping logic activates. Thus the class works for any relationship between the size of nums and the requested rank k.
Performance Optimizations
The use of heapify is a primary optimization. By converting the entire input list into a heap in one operation, the constructor avoids the overhead of inserting each element individually, which would require repeated rebalancing. This approach reduces the work needed to establish the initial heap structure.
Maintaining the heap at a fixed size of k eliminates unnecessary growth. Each insertion is followed by at most one removal, ensuring that the heap never exceeds k+1 elements. This bounded size keeps the internal heap operations cheap, as the cost of heappush and heappop depends on the current heap height, which is limited by k.
The decision to store only the k largest values means that memory consumption is directly proportional to k, regardless of how many values are added over the lifetime of the object. This selective retention avoids the linear growth that a naïve approach of storing all elements would incur.
By returning the root of the heap (self.heap[0]) after each addition, the implementation provides immediate access to the result without additional traversal or computation. This direct retrieval leverages the heap property that the smallest element is always at index zero.
ELI5 - Simplified Explanation
Imagine a magical toy bucket that only likes to keep track of a few of the biggest blocks. The code starts by setting a special number called k, which tells the bucket how many big blocks to hold onto. If the bucket has too many blocks inside, it does a little cleaning and tosses out the smallest ones until it matches the number k.
When a brand new block arrives, the bucket welcomes it inside. After adding the new block, the bucket checks to see if it has become too crowded again. If the bucket is suddenly holding more blocks than its limit, it quickly finds the smallest block currently sitting inside and lets it go. This keeps the bucket perfectly filled with only the absolute largest blocks that have been put in so far. The very smallest block among those champions is always waiting right at the very front for whenever someone wants to peek at it.
Code Quality
Complexity Analysis
As a rule of thumb, the maximum input size for one second execution time is
- factorial: up to 10 elements
- exponential: up to 20 elements
- polynomial: a few thousand elements
- loglinear: up to 100,000 elements
- linear: a few million elements
- logarithmic: a billion elements
- constant: practically unlimited
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| author | solutions | ||||||||||
| www | AlgoMonster | C++ | Java | Python | TS | ||||||
| WalkCCC | C++ | Java | |||||||||
| leetcode.ca | C++ | Java | Python | JS | Go | TS | |||||
| LeetcodeHelp | C++ | Java | Python | ||||||||
| Progiez | C++ | Java | Python | ||||||||
| github | BigEggStudy | C# | |||||||||
| black-shadows | C++ | ||||||||||
| bujosa | Python | ||||||||||
| charles-wangkai | Java | ||||||||||
| Dijkstra-Edu | Java | ||||||||||
| everthis | JS | ||||||||||
| fartem | Ruby | ||||||||||
| FelixFan1122 | Java | ||||||||||
| fpdjsns | C++ | ||||||||||
| halfrost | Go | ||||||||||
| JoshCrozier | JS | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| qiyuangong | Java | ||||||||||
| ruoru | Rust | ||||||||||
| Shamik07 | Dart | ||||||||||
| shreymehul | C# | ||||||||||
| sonugiri1043 | C++ | ||||||||||
| suxrobGM | C# | ||||||||||
| varunu28 | Java | ||||||||||
| withaarzoo | C++ | ||||||||||
| YuriSpiridonov | Python | ||||||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||||||
| WalkCCC | C++, Java | ||||||||||
| leetcode.ca | C++, Go, Java, JavaScript, Python, TypeScript | ||||||||||
| LeetcodeHelp | C++, Java, Python | ||||||||||
| Progiez | C++, Java, Python | ||||||||||
| BigEggStudy | C# | ||||||||||
| black-shadows | C++, C++ | ||||||||||
| bujosa | Python | ||||||||||
| charles-wangkai | Java | ||||||||||
| Dijkstra-Edu | Java | ||||||||||
| everthis | JavaScript | ||||||||||
| fartem | Ruby | ||||||||||
| FelixFan1122 | Java | ||||||||||
| fpdjsns | C++ | ||||||||||
| halfrost | Go | ||||||||||
| JoshCrozier | JavaScript | ||||||||||
| keineahnung2345 | C++ | ||||||||||
| lkwq007 | Python | ||||||||||
| qiyuangong | Java | ||||||||||
| ruoru | Rust | ||||||||||
| Shamik07 | Dart | ||||||||||
| shreymehul | C# | ||||||||||
| sonugiri1043 | C++ | ||||||||||
| suxrobGM | C# | ||||||||||
| varunu28 | Java | ||||||||||
| withaarzoo | C++ | ||||||||||
| YuriSpiridonov | Python |
Videos
Similar Problems
- problem 215: Kth Largest Element in an Array
- problem 1825: Finding MK Average
Solved On The Same Day
- problem 144: Binary Tree Preorder Traversal
- problem 145: Binary Tree Postorder Traversal
- problem 222: Count Complete Tree Nodes
- problem 404: Sum of Left Leaves
- problem 501: Find Mode in Binary Search Tree
- problem 543: Diameter of Binary Tree
- problem 559: Maximum Depth of N-ary Tree
- problem 589: N-ary Tree Preorder Traversal
- problem 590: N-ary Tree Postorder Traversal
- problem 637: Average of Levels in Binary Tree
- problem 700: Search in a Binary Search Tree
- problem 79: Word Search
- problem 81: Search in Rotated Sorted Array II
- problem 97: Interleaving String
- problem 99: Recover Binary Search Tree
- problem 173: Binary Search Tree Iterator
- problem 199: Binary Tree Right Side View
- problem 230: Kth Smallest Element in a BST
- problem 235: Lowest Common Ancestor of a Binary Search Tree
- problem 341: Flatten Nested List Iterator
- problem 429: N-ary Tree Level Order Traversal
- problem 508: Most Frequent Subtree Sum
- problem 513: Find Bottom Left Tree Value
- problem 538: Convert BST to Greater Tree
- problem 65: Valid Number
- problem 85: Maximal Rectangle
- problem 87: Scramble String
- problem 126: Word Ladder II
- problem 127: Word Ladder
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality