Skip to content

Commit 97c06cf

Browse files
committed
Top 'K' Numbers
1 parent c388c7c commit 97c06cf

File tree

6 files changed

+189
-0
lines changed

6 files changed

+189
-0
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
"Techer",
169169
"Tencent",
170170
"Thakur",
171+
"Timsort",
171172
"Tushar",
172173
"Tweety",
173174
"Twilio",
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.TopKNumbers.Java;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.PriorityQueue;
6+
7+
public class Solution {
8+
public static void main(String[] args) {
9+
List<Integer> result = findKLargestNumbers(new int[] {3, 1, 5, 12, 2, 11}, 3);
10+
System.out.println("Here are the top K numbers: " + result);
11+
12+
result = findKLargestNumbers(new int[] {5, 12, 11, -1, 12}, 3);
13+
System.out.println("Here are the top K numbers: " + result);
14+
}
15+
16+
public static List<Integer> findKLargestNumbers(int[] nums, int k) {
17+
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>((n1, n2) -> n1 - n2);
18+
// put first 'K' numbers in the min heap
19+
for (int i = 0; i < k; i++)
20+
minHeap.add(nums[i]);
21+
22+
// go through the remaining numbers of the array, if the number from the array is bigger
23+
// than the
24+
// top (smallest) number of the min-heap, remove the top number from heap and add the number
25+
// from array
26+
for (int i = k; i < nums.length; i++) {
27+
if (nums[i] > minHeap.peek()) {
28+
minHeap.poll();
29+
minHeap.add(nums[i]);
30+
}
31+
}
32+
33+
// the heap has the top 'K' numbers, return them in a list
34+
return new ArrayList<>(minHeap);
35+
}
36+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package EducativeIo.Courses.GrokkingTheCodingInterview.Ch13_TopKElements.TopKNumbers.Java;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import java.time.Duration;
6+
import java.util.Arrays;
7+
import java.util.List;
8+
import org.junit.jupiter.api.Test;
9+
import org.junit.jupiter.api.AfterEach;
10+
import org.junit.jupiter.api.BeforeEach;
11+
12+
public class SolutionTest {
13+
14+
Solution solution;
15+
16+
@BeforeEach
17+
public void setUp() throws Exception {
18+
solution = new Solution();
19+
}
20+
21+
@AfterEach
22+
public void tearDown() throws Exception {
23+
solution = null;
24+
}
25+
26+
@Test
27+
public void MainFunction() {
28+
assertTimeout(Duration.ofMillis(500), () -> {
29+
String[] args = new String[0];
30+
assertAll(() -> Solution.main(args));
31+
});
32+
}
33+
34+
@Test
35+
public void TrivialCase1() {
36+
int[] nums = new int[] {3, 1, 5, 12, 2, 11};
37+
int k = 3;
38+
assertTimeout(Duration.ofMillis(500), () -> {
39+
List<Integer> expected = Arrays.asList(5, 12, 11);
40+
List<Integer> actual = Solution.findKLargestNumbers(nums, k);
41+
assertEquals(expected, actual);
42+
});
43+
}
44+
45+
@Test
46+
public void TrivialCase2() {
47+
int[] nums = new int[] {5, 12, 11, -1, 12};
48+
int k = 3;
49+
assertTimeout(Duration.ofMillis(500), () -> {
50+
List<Integer> expected = Arrays.asList(11, 12, 12);
51+
List<Integer> actual = Solution.findKLargestNumbers(nums, k);
52+
assertEquals(expected, actual);
53+
});
54+
}
55+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"type": "Coding",
3+
"name": "Top 'K' Numbers",
4+
"origin": {
5+
"name": "Educative",
6+
"link": "https://www.educative.io/courses/grokking-the-coding-interview/RM535yM9DW0"
7+
},
8+
"companies": ["", ""],
9+
"categories": [{
10+
"name": "Courses",
11+
"children": [{
12+
"name": "Grokking the Coding Interview: Patterns for Coding Questions",
13+
"children": []
14+
}]
15+
},
16+
{
17+
"name": "Difficulty",
18+
"children": [{
19+
"name": "Easy",
20+
"children": []
21+
}]
22+
},
23+
{
24+
"name": "Pattern",
25+
"children": [{
26+
"name": "Top K Elements",
27+
"children": []
28+
}]
29+
}
30+
],
31+
"tags": ["Top K Elements"],
32+
"buckets": []
33+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Problem Definition
2+
3+
## Description
4+
5+
Given an unsorted array of numbers, find the ‘K’ largest numbers in it.
6+
7+
Note: For a detailed discussion about different approaches to solve this problem, take a look at **Kth Smallest Number**.
8+
9+
Example 1:
10+
11+
```plaintext
12+
Input: [3, 1, 5, 12, 2, 11], K = 3
13+
Output: [5, 12, 11]
14+
```
15+
16+
Example 2:
17+
18+
```plaintext
19+
Input: [5, 12, 11, -1, 12], K = 3
20+
Output: [12, 11, 12]
21+
```
22+
23+
## Discussion
24+
25+
A brute force solution could be to sort the array and return the largest K numbers. The time complexity of such an algorithm will be O(N*logN as we need to use a sorting algorithm like [Timsort](https://en.wikipedia.org/wiki/Timsort) if we use Java’s `Collection.sort()`.
26+
27+
The best data structure that comes to mind to keep track of top ‘K’ elements is [Heap](https://en.wikipedia.org/wiki/Heap_(data_structure)). Let’s see if we can use a heap to find a better algorithm.
28+
29+
If we iterate through the array one element at a time and keep ‘K’ largest numbers in a heap such that each time we find a larger number than the smallest number in the heap, we do two things:
30+
31+
1. Take out the smallest number from the heap, and
32+
2. Insert the larger number into the heap.
33+
34+
This will ensure that we always have ‘K’ largest numbers in the heap. The most efficient way to repeatedly find the smallest number among a set of numbers will be to use a min-heap. As we know, we can find the smallest number in a min-heap in constant time O(1), since the smallest number is always at the root of the heap. Extracting the smallest number from a min-heap will take O(logN) (if the heap has ‘N’ elements) as the heap needs to readjust after the removal of an element.
35+
36+
Let’s take Example-1 to go through each step of our algorithm:
37+
38+
Given array: [3, 1, 5, 12, 2, 11], and K=3
39+
40+
1. First, let’s insert ‘K’ elements in the min-heap.
41+
2. After the insertion, the heap will have three numbers [3, 1, 5] with ‘1’ being the root as it is the smallest element.
42+
3. We’ll iterate through the remaining numbers and perform the above-mentioned two steps if we find a number larger than the root of the heap.
43+
4. The 4th number is ‘12’ which is larger than the root (which is ‘1’), so let’s take out ‘1’ and insert ‘12’. Now the heap will have [3, 5, 12] with ‘3’ being the root as it is the smallest element.
44+
5. The 5th number is ‘2’ which is not bigger than the root of the heap (‘3’), so we can skip this as we already have top three numbers in the heap.
45+
6. The last number is ‘11’ which is bigger than the root (which is ‘3’), so let’s take out ‘3’ and insert ‘11’. Finally, the heap has the largest three numbers: [5, 12, 11]
46+
47+
It will take us O(logK) to extract the minimum number from the min-heap. So the overall time complexity of our algorithm will be O(K\*logK+(N-K)\*logK) since, first, we insert ‘K’ numbers in the heap and then iterate through the remaining numbers and at every step, in the worst case, we need to extract the minimum number and insert a new number in the heap. This algorithm is better than O(N*logN).
48+
49+
### Time Complexity
50+
51+
The time complexity of this algorithm is O(K\*logK+(N-K)\*logK), which is asymptotically equal to O(N*logK)
52+
53+
### Space Complexity
54+
55+
The space complexity will be O(K) since we need to store the top ‘K’ numbers in the heap.
56+
57+
## Notes
58+
59+
## References
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Introduction
2+
3+
Any problem that asks us to find the top/smallest/frequent ‘K’ elements among a given set falls under this pattern.
4+
5+
The best data structure that comes to mind to keep track of ‘K’ elements is [Heap](https://en.wikipedia.org/wiki/Heap_(data_structure)). This pattern will make use of the Heap to solve multiple problems dealing with ‘K’ elements at a time from a set of given elements.

0 commit comments

Comments
 (0)