From 21c41cfd99b78d9496f9767b6aa1c3e9c329162d Mon Sep 17 00:00:00 2001 From: Mansi Date: Sat, 6 Jan 2018 08:08:02 +0530 Subject: [PATCH] BAEL-1297 Find kth largest element in a sequence of numbers (#3332) * Example Code For Evaluation Article This is an example code for the evaluation article on "Different Types of Bean Injection in Spring" * Added unit tests * Minor changes to application context * Removed code committed for evaluation article * BAEL-944 Demonstrating the problems with new Url pattern matching in Spring 5 * BAEL-944 Demonstrating the problems with new Url pattern matching in Spring 5 * BAEL-944 Exploring the Spring MVC URL Matching Improvements * BAEL-944 Exploring the Spring MVC URL Matching Improvements * BAEL-944 Exploring the Spring MVC URL Matching Improvements * BAEL-944 Code Formatting and solving build issue * BAEL-944 Resolving build issue due to change in Spring version * BAEL-944 Resolving build issue * BAEL-944 Formatting code * BAEL-944 Moving tests to correct package * BAEL-944 Moving tests to correct package * BAEL-944 Replacing @RequestMapping by @GetMapping * BAEL-944 Remove unnecessary attribute name, "value" in annotations * BAEL-79 Intro to Activiti with Spring * BAEL-79 Intro to Activiti with Spring * BAEL-79 Adding activiti module to the parent modules * BAEL-79 Using latest version * BAEL-79 Update Spring boot version that works with Activiti * BAEL-79 Replace RequestMapping with GetMapping * BAEL-79 Use Java 8 Syntax * BAEL-79 Formatting * BAEL-79 changed module name * BAEL-378 A Guide to Activiti with Java * BAEL-79 Fixed unit tests * BAEL-79 Simplified the process * BAEL-79 Fix test cases * BAEL-1045 Lambda Behave * BAEL-1045 Lambda Behave * BAEL-1045 Lambda Behave * BAEL-1090 Difference between compact and compressed strings in Java 9 * BAEL-1237 String Formatter * BAEL-1237 String Formatter * BAEL-1237 String Formatter * BAEL-1237 String Formatter * BAEL-1237 Guide to java.util.Formatter * BAEL-1297 Find kth largest element in a sequence of numbers * BAEL-1297 fixed issues and modified file name * BAEL-1297 Modified randomized quickselect * BAEL-1297 added additional sorting method * BAEL-1297 UnitTest fix * BAEL-1297 Additional method Added QuickSelect With Iterative Partition method * BAEL-1297 Added AssertJ annotations * BAEL-1297 added missing assertj dependancy --- algorithms/pom.xml | 6 + .../algorithms/kthlargest/FindKthLargest.java | 111 ++++++++++++++++++ .../kthlargest/FindKthLargestUnitTest.java | 57 +++++++++ 3 files changed, 174 insertions(+) create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/kthlargest/FindKthLargest.java create mode 100644 algorithms/src/test/java/com/baeldung/algorithms/kthlargest/FindKthLargestUnitTest.java 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); + } + +}