diff --git a/algorithms/pom.xml b/algorithms/pom.xml
index e972f39494..2eb8cd42b6 100644
--- a/algorithms/pom.xml
+++ b/algorithms/pom.xml
@@ -39,6 +39,12 @@
jgrapht-core
1.0.1
+
+ org.assertj
+ assertj-core
+ 3.9.0
+ test
+
diff --git a/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java b/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java
new file mode 100644
index 0000000000..822abdae02
--- /dev/null
+++ b/algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java
@@ -0,0 +1,111 @@
+package com.baeldung.algorithms.kthlargest;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.stream.IntStream;
+
+public class FindKthLargest {
+
+ public int findKthLargestBySorting(Integer[] arr, int k) {
+ Arrays.sort(arr);
+ int targetIndex = arr.length - k;
+ return arr[targetIndex];
+ }
+
+ public int findKthLargestBySortingDesc(Integer[] arr, int k) {
+ Arrays.sort(arr, Collections.reverseOrder());
+ return arr[k - 1];
+ }
+
+ public int findKthElementByQuickSelect(Integer[] arr, int left, int right, int k) {
+ if (k >= 0 && k <= right - left + 1) {
+ int pos = partition(arr, left, right);
+ if (pos - left == k) {
+ return arr[pos];
+ }
+ if (pos - left > k) {
+ return findKthElementByQuickSelect(arr, left, pos - 1, k);
+ }
+ return findKthElementByQuickSelect(arr, pos + 1, right, k - pos + left - 1);
+ }
+ return 0;
+ }
+
+ public int findKthElementByQuickSelectWithIterativePartition(Integer[] arr, int left, int right, int k) {
+ if (k >= 0 && k <= right - left + 1) {
+ int pos = partitionIterative(arr, left, right);
+ if (pos - left == k) {
+ return arr[pos];
+ }
+ if (pos - left > k) {
+ return findKthElementByQuickSelectWithIterativePartition(arr, left, pos - 1, k);
+ }
+ return findKthElementByQuickSelectWithIterativePartition(arr, pos + 1, right, k - pos + left - 1);
+ }
+ return 0;
+ }
+
+ private int partition(Integer[] arr, int left, int right) {
+ int pivot = arr[right];
+ Integer[] leftArr;
+ Integer[] rightArr;
+
+ leftArr = IntStream.range(left, right)
+ .filter(i -> arr[i] < pivot)
+ .map(i -> arr[i])
+ .boxed()
+ .toArray(Integer[]::new);
+
+ rightArr = IntStream.range(left, right)
+ .filter(i -> arr[i] > pivot)
+ .map(i -> arr[i])
+ .boxed()
+ .toArray(Integer[]::new);
+
+ int leftArraySize = leftArr.length;
+ System.arraycopy(leftArr, 0, arr, left, leftArraySize);
+ arr[leftArraySize + left] = pivot;
+ System.arraycopy(rightArr, 0, arr, left + leftArraySize + 1, rightArr.length);
+
+ return left + leftArraySize;
+ }
+
+ private int partitionIterative(Integer[] arr, int left, int right) {
+ int pivot = arr[right], i = left;
+ for (int j = left; j <= right - 1; j++) {
+ if (arr[j] <= pivot) {
+ swap(arr, i, j);
+ i++;
+ }
+ }
+ swap(arr, i, right);
+ return i;
+ }
+
+ public int findKthElementByRandomizedQuickSelect(Integer[] arr, int left, int right, int k) {
+ if (k >= 0 && k <= right - left + 1) {
+ int pos = randomPartition(arr, left, right);
+ if (pos - left == k) {
+ return arr[pos];
+ }
+ if (pos - left > k) {
+ return findKthElementByRandomizedQuickSelect(arr, left, pos - 1, k);
+ }
+ return findKthElementByRandomizedQuickSelect(arr, pos + 1, right, k - pos + left - 1);
+ }
+ return 0;
+ }
+
+ private int randomPartition(Integer arr[], int left, int right) {
+ int n = right - left + 1;
+ int pivot = (int) (Math.random()) % n;
+ swap(arr, left + pivot, right);
+ return partition(arr, left, right);
+ }
+
+ private void swap(Integer[] arr, int n1, int n2) {
+ int temp = arr[n2];
+ arr[n2] = arr[n1];
+ arr[n1] = temp;
+ }
+}
diff --git a/algorithms/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java
new file mode 100644
index 0000000000..6fbb7c163a
--- /dev/null
+++ b/algorithms/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java
@@ -0,0 +1,57 @@
+package com.baeldung.algorithms.kthlargest;
+
+import static org.assertj.core.api.Assertions.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class FindKthLargestUnitTest {
+
+ private FindKthLargest findKthLargest;
+ private Integer[] arr = { 3, 7, 1, 2, 8, 10, 4, 5, 6, 9 };
+
+ @Before
+ public void setup() {
+ findKthLargest = new FindKthLargest();
+ }
+
+ @Test
+ public void givenIntArray_whenFindKthLargestBySorting_thenGetResult() {
+ int k = 3;
+ assertThat(findKthLargest.findKthLargestBySorting(arr, k)).isEqualTo(8);
+ }
+
+ @Test
+ public void givenIntArray_whenFindKthLargestBySortingDesc_thenGetResult() {
+ int k = 3;
+ assertThat(findKthLargest.findKthLargestBySortingDesc(arr, k)).isEqualTo(8);
+ }
+
+ @Test
+ public void givenIntArray_whenFindKthLargestByQuickSelect_thenGetResult() {
+ int k = 3;
+ int kthLargest = arr.length - k;
+ assertThat(findKthLargest.findKthElementByQuickSelect(arr, 0, arr.length - 1, kthLargest)).isEqualTo(8);
+ }
+
+ @Test
+ public void givenIntArray_whenFindKthElementByQuickSelectIterative_thenGetResult() {
+ int k = 3;
+ int kthLargest = arr.length - k;
+ assertThat(findKthLargest.findKthElementByQuickSelectWithIterativePartition(arr, 0, arr.length - 1, kthLargest)).isEqualTo(8);
+ }
+
+ @Test
+ public void givenIntArray_whenFindKthSmallestByQuickSelect_thenGetResult() {
+ int k = 3;
+ assertThat(findKthLargest.findKthElementByQuickSelect(arr, 0, arr.length - 1, k - 1)).isEqualTo(3);
+ }
+
+ @Test
+ public void givenIntArray_whenFindKthLargestByRandomizedQuickSelect_thenGetResult() {
+ int k = 3;
+ int kthLargest = arr.length - k;
+ assertThat(findKthLargest.findKthElementByRandomizedQuickSelect(arr, 0, arr.length - 1, kthLargest)).isEqualTo(8);
+ }
+
+}