Skip to content

Commit 5048c2c

Browse files
author
alxkm
committed
refactor: FindKthNumber
1 parent ce4eb55 commit 5048c2c

File tree

2 files changed

+103
-51
lines changed

2 files changed

+103
-51
lines changed
Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,65 @@
11
package com.thealgorithms.maths;
22

3-
import java.util.Arrays;
43
import java.util.Random;
54

65
/**
7-
* use quick sort algorithm to get kth largest or kth smallest element in given array
6+
* Use a quicksort-based approach to identify the k-th largest or k-th max element within the provided array.
87
*/
98
public final class FindKthNumber {
109
private FindKthNumber() {
1110
}
1211

1312
private static final Random RANDOM = new Random();
1413

15-
public static void main(String[] args) {
16-
/* generate an array with random size and random elements */
17-
int[] nums = generateArray(100);
18-
19-
/* get 3th largest element */
20-
int kth = 3;
21-
int kthMaxIndex = nums.length - kth;
22-
int targetMax = findKthMax(nums, kthMaxIndex);
23-
24-
/* get 3th smallest element */
25-
int kthMinIndex = kth - 1;
26-
int targetMin = findKthMax(nums, kthMinIndex);
14+
public static int findKthMax(int[] array, int k) {
15+
if (k <= 0 || k > array.length) {
16+
throw new IllegalArgumentException("k must be between 1 and the size of the array");
17+
}
2718

28-
Arrays.sort(nums);
29-
assert nums[kthMaxIndex] == targetMax;
30-
assert nums[kthMinIndex] == targetMin;
19+
// Convert k-th largest to index for QuickSelect
20+
return quickSelect(array, 0, array.length - 1, array.length - k);
3121
}
3222

33-
private static int[] generateArray(int capacity) {
34-
int size = RANDOM.nextInt(capacity) + 1;
35-
int[] array = new int[size];
36-
37-
for (int i = 0; i < size; i++) {
38-
array[i] = RANDOM.nextInt() % 100;
23+
private static int quickSelect(int[] array, int left, int right, int kSmallest) {
24+
if (left == right) {
25+
return array[left];
3926
}
40-
return array;
41-
}
4227

43-
private static int findKthMax(int[] nums, int k) {
44-
int start = 0;
45-
int end = nums.length;
46-
while (start < end) {
47-
int pivot = partition(nums, start, end);
48-
if (k == pivot) {
49-
return nums[pivot];
50-
} else if (k > pivot) {
51-
start = pivot + 1;
52-
} else {
53-
end = pivot;
54-
}
28+
// Randomly select a pivot index
29+
int pivotIndex = left + RANDOM.nextInt(right - left + 1);
30+
pivotIndex = partition(array, left, right, pivotIndex);
31+
32+
if (kSmallest == pivotIndex) {
33+
return array[kSmallest];
34+
} else if (kSmallest < pivotIndex) {
35+
return quickSelect(array, left, pivotIndex - 1, kSmallest);
36+
} else {
37+
return quickSelect(array, pivotIndex + 1, right, kSmallest);
5538
}
56-
return -1;
5739
}
5840

59-
private static int partition(int[] nums, int start, int end) {
60-
int pivot = nums[start];
61-
int j = start;
62-
for (int i = start + 1; i < end; i++) {
63-
if (nums[i] < pivot) {
64-
j++;
65-
swap(nums, i, j);
41+
private static int partition(int[] array, int left, int right, int pivotIndex) {
42+
int pivotValue = array[pivotIndex];
43+
// Move pivot to end
44+
swap(array, pivotIndex, right);
45+
int storeIndex = left;
46+
47+
// Move all smaller elements to the left
48+
for (int i = left; i < right; i++) {
49+
if (array[i] < pivotValue) {
50+
swap(array, storeIndex, i);
51+
storeIndex++;
6652
}
6753
}
68-
swap(nums, start, j);
69-
return j;
54+
55+
// Move pivot to its final place
56+
swap(array, storeIndex, right);
57+
return storeIndex;
7058
}
7159

72-
private static void swap(int[] nums, int a, int b) {
73-
int tmp = nums[a];
74-
nums[a] = nums[b];
75-
nums[b] = tmp;
60+
private static void swap(int[] array, int i, int j) {
61+
int temp = array[i];
62+
array[i] = array[j];
63+
array[j] = temp;
7664
}
7765
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.thealgorithms.maths;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import java.util.Arrays;
7+
import java.util.Random;
8+
9+
import org.junit.jupiter.api.Test;
10+
11+
public class FindKthNumberTest {
12+
@Test
13+
public void testFindKthMaxTypicalCases() {
14+
int[] array1 = { 3, 2, 1, 4, 5 };
15+
assertEquals(3, FindKthNumber.findKthMax(array1, 3));
16+
assertEquals(4, FindKthNumber.findKthMax(array1, 2));
17+
assertEquals(5, FindKthNumber.findKthMax(array1, 1));
18+
19+
int[] array2 = { 7, 5, 8, 2, 1, 6 };
20+
assertEquals(5, FindKthNumber.findKthMax(array2, 4));
21+
assertEquals(6, FindKthNumber.findKthMax(array2, 3));
22+
assertEquals(8, FindKthNumber.findKthMax(array2, 1));
23+
}
24+
25+
@Test
26+
public void testFindKthMaxEdgeCases() {
27+
int[] array1 = { 1 };
28+
assertEquals(1, FindKthNumber.findKthMax(array1, 1));
29+
30+
int[] array2 = { 5, 3 };
31+
assertEquals(5, FindKthNumber.findKthMax(array2, 1));
32+
assertEquals(3, FindKthNumber.findKthMax(array2, 2));
33+
}
34+
35+
@Test
36+
public void testFindKthMaxInvalidK() {
37+
int[] array = { 1, 2, 3, 4, 5 };
38+
assertThrows(IllegalArgumentException.class, () -> {
39+
FindKthNumber.findKthMax(array, 0);
40+
});
41+
assertThrows(IllegalArgumentException.class, () -> {
42+
FindKthNumber.findKthMax(array, 6);
43+
});
44+
}
45+
46+
@Test
47+
public void testFindKthMaxLargeArray() {
48+
int[] array = generateArray(1000);
49+
int k = new Random().nextInt(array.length);
50+
int result = FindKthNumber.findKthMax(array, k);
51+
Arrays.sort(array);
52+
assertEquals(array[array.length - k], result);
53+
}
54+
55+
public static int[] generateArray(int capacity) {
56+
int size = new Random().nextInt(capacity) + 1;
57+
int[] array = new int[size];
58+
59+
for (int i = 0; i < size; i++) {
60+
array[i] = new Random().nextInt(100); // Ensure positive values for testing
61+
}
62+
return array;
63+
}
64+
}

0 commit comments

Comments
 (0)