Skip to content

Commit 925d39c

Browse files
committed
Kth largest element in an array
1 parent 670520c commit 925d39c

File tree

2 files changed

+170
-0
lines changed

2 files changed

+170
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// 215. Kth largest element in an array
2+
// Topics: 'Heap (Priority Queue)', 'Sorting', 'Quickselect', 'Divide and Conquer', 'Array'
3+
// Level: 'Medium'
4+
5+
// Given an integer array nums and an integer k, return the kth largest element in the array.
6+
7+
// Note that it is the kth largest element in the sorted order, not the kth distinct element.
8+
9+
// Can you solve it without sorting?
10+
11+
// Example 1:
12+
13+
// Input: nums = [3,2,1,5,6,4], k = 2
14+
// Output: 5
15+
16+
// Example 2:
17+
18+
// Input: nums = [3,2,3,1,2,4,5,5,6], k = 4
19+
// Output: 4
20+
21+
// Constraints:
22+
23+
// 1 <= k <= nums.length <= 105
24+
// -104 <= nums[i] <= 104
25+
26+
package kthlargestelementinanarray
27+
28+
func findKthLargest(nums []int, max int) int {
29+
arr := []int{}
30+
for i, n := range nums {
31+
if i < max {
32+
arr = append(arr, n)
33+
j := len(arr) - 1
34+
for j > 0 && arr[j] < arr[(j-1)/2] {
35+
arr[j], arr[(j-1)/2] = arr[(j-1)/2], arr[j]
36+
j = (j - 1) / 2
37+
}
38+
} else if n > arr[0] {
39+
arr[0] = n
40+
j := 0
41+
for 2*j+1 < len(arr) {
42+
if 2*j+2 < len(arr) && arr[2*j+2] < arr[2*j+1] && arr[j] > arr[2*j+2] {
43+
arr[j], arr[2*j+2] = arr[2*j+2], arr[j]
44+
j = 2*j + 2
45+
} else if arr[j] > arr[2*j+1] {
46+
arr[j], arr[2*j+1] = arr[2*j+1], arr[j]
47+
j = 2*j + 1
48+
} else {
49+
break
50+
}
51+
}
52+
}
53+
}
54+
return arr[0]
55+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package kthlargestelementinanarray
2+
3+
import "testing"
4+
5+
func TestFindKthLargest(t *testing.T) {
6+
tests := []struct {
7+
name string
8+
nums []int
9+
k int
10+
want int
11+
}{
12+
{
13+
name: "example 1",
14+
nums: []int{3, 2, 1, 5, 6, 4},
15+
k: 2,
16+
want: 5,
17+
},
18+
{
19+
name: "example 2",
20+
nums: []int{3, 2, 3, 1, 2, 4, 5, 5, 6},
21+
k: 4,
22+
want: 4,
23+
},
24+
{
25+
name: "single element",
26+
nums: []int{1},
27+
k: 1,
28+
want: 1,
29+
},
30+
{
31+
name: "k equals 1",
32+
nums: []int{3, 2, 1, 5, 6, 4},
33+
k: 1,
34+
want: 6,
35+
},
36+
{
37+
name: "k equals array length",
38+
nums: []int{3, 2, 1, 5, 6, 4},
39+
k: 6,
40+
want: 1,
41+
},
42+
{
43+
name: "all same elements",
44+
nums: []int{5, 5, 5, 5, 5},
45+
k: 3,
46+
want: 5,
47+
},
48+
{
49+
name: "negative numbers",
50+
nums: []int{-1, -2, -3, -4, -5},
51+
k: 2,
52+
want: -2,
53+
},
54+
{
55+
name: "mixed positive and negative",
56+
nums: []int{-3, 2, -1, 5, -6, 4},
57+
k: 3,
58+
want: 2,
59+
},
60+
{
61+
name: "two elements",
62+
nums: []int{2, 1},
63+
k: 1,
64+
want: 2,
65+
},
66+
{
67+
name: "two elements k=2",
68+
nums: []int{2, 1},
69+
k: 2,
70+
want: 1,
71+
},
72+
{
73+
name: "already sorted ascending",
74+
nums: []int{1, 2, 3, 4, 5},
75+
k: 2,
76+
want: 4,
77+
},
78+
{
79+
name: "already sorted descending",
80+
nums: []int{5, 4, 3, 2, 1},
81+
k: 2,
82+
want: 4,
83+
},
84+
{
85+
name: "duplicates at boundaries",
86+
nums: []int{1, 1, 1, 2, 2, 3, 3, 3, 3},
87+
k: 4,
88+
want: 3,
89+
},
90+
{
91+
name: "large values",
92+
nums: []int{10000, 9999, 9998, 9997, 9996},
93+
k: 3,
94+
want: 9998,
95+
},
96+
{
97+
name: "small values",
98+
nums: []int{-10000, -9999, -9998, -9997, -9996},
99+
k: 3,
100+
want: -9998,
101+
},
102+
}
103+
104+
for _, tt := range tests {
105+
t.Run(tt.name, func(t *testing.T) {
106+
numsCopy := make([]int, len(tt.nums))
107+
copy(numsCopy, tt.nums)
108+
109+
got := findKthLargest(numsCopy, tt.k)
110+
if got != tt.want {
111+
t.Errorf("findKthLargest(%v, %d) = %d, want %d", tt.nums, tt.k, got, tt.want)
112+
}
113+
})
114+
}
115+
}

0 commit comments

Comments
 (0)