Find k largest elements in an array (original) (raw)
Given an array arr[] and an integer k, the task is to find **k largest elements in the given array. Elements in the output array should be in decreasing order.
**Examples:
**Input: [1, 23, 12, 9, 30, 2, 50], k = 3
**Output: [50, 30, 23]**Input: [11, 5, 12, 9, 44, 17, 2], k = 2
**Output: [44, 17]
Table of Content
- [Naive Approach] Using Sorting
- [Expected Approach] Using Priority Queue(Min-Heap)
- [Alternate Approach] Using Quick Select algorithm - O(n^2) in Worst
[Naive Approach] Using Sorting
The idea is to sort the input array in **descending order, so the first **k elements in the array will be the **k largest elements.
C++ `
// C++ program to find k largest elements in an // array using sorting
#include #include #include using namespace std;
vector kLargest(vector &arr, int k) {
// sort the given array in descending order
sort(arr.begin(), arr.end(), greater<int>());
// store the first k element in result array
vector<int> res(arr.begin(), arr.begin() + k);
return res;}
int main() { vectorarr = {1, 23, 12, 9, 30, 2, 50}; int k = 3;
vector<int> res = kLargest(arr, k);
for(int ele : res)
cout << ele << " ";
return 0;}
Java
// Java program to find k largest elements in an array using // sorting
import java.util.*;
class GfG { static ArrayList kLargest(int[] arr, int k) { int n = arr.length;
// Convert int type to Integer
// for sorting with a comparator
Integer[] arrInteger =
Arrays.stream(arr).boxed().toArray(Integer[]::new);
// Sort the array in descending order
Arrays.sort(arrInteger, Collections.reverseOrder());
// Store the first k elements in result list
ArrayList<Integer> res = new ArrayList<>();
for (int i = 0; i < k; i++)
res.add(arrInteger[i]);
return res;
}
public static void main(String[] args) {
int[] arr = {1, 23, 12, 9, 30, 2, 50};
int k = 3;
ArrayList<Integer> res = kLargest(arr, k);
for (int ele : res)
System.out.print(ele + " ");
}}
Python
Python program to find k largest elements in an
array using sorting
def kLargest(arr, k):
# sort the given array in descending order
arr.sort(reverse=True)
# store the first k elements in result list
res = arr[:k]
return resif name == "main": arr = [1, 23, 12, 9, 30, 2, 50] k = 3 res = kLargest(arr, k) print(' '.join(map(str, res)))
C#
// C# program to find k largest elements in an // array using sorting
using System; using System.Collections.Generic; using System.Linq;
class GfG { static List kLargest(int[] arr, int k) {
// sort the given array in descending order
Array.Sort(arr, (a, b) => b.CompareTo(a));
// store the first k elements in result list
List<int> res = new List<int>();
for (int i = 0; i < k; i++) {
res.Add(arr[i]);
}
return res;
}
static void Main() {
int[] arr = {1, 23, 12, 9, 30, 2, 50};
int k = 3;
List<int> res = kLargest(arr, k);
foreach (int ele in res)
Console.Write(ele + " ");
}}
JavaScript
// JavaScript program to find k largest elements
// in an array using sorting
function kLargest(arr, k) {
// sort the given array in descending order
arr.sort((a, b) => b - a);
// store the first k elements in result array
let res = arr.slice(0, k);
return res;}
// Driver Code const arr = [1, 23, 12, 9, 30, 2, 50]; const k = 3; const res = kLargest(arr, k); console.log(res.join(' '));
`
**Time complexity: O(n * log n)
**Auxiliary Space: O(1)
[Expected Approach] Using Priority Queue(Min-Heap)
The idea is, as we **iterate through the array, we keep track of the **k largest elements at each step. To do this, we use a **min-heap. First, we insert the **initial k elements into the min-heap. After that, for each next element, we compare it with the **top of the heap. Since the **top element of the min-heap is the **smallest among the k elements, if the current element is **larger than the top, it means the top element is no longer one of the k largest elements. In this case, we **remove the top and **insert the larger element. After completing the entire traversal, the heap will contain exactly the k largest elements of the array.
C++ `
// C++ program to find the k largest elements in the
// array using min heap
#include #include #include #include using namespace std;
// Function to find the k largest elements in the array vector kLargest(vector &arr, int k) {
// Min Priority Queue (Min-Heap) with first k
// elements of the array
priority_queue<int, vector<int>, greater<int>>
minH(arr.begin(), arr.begin() + k);
// Travers n - k elements
for (int i = k; i < arr.size(); i++) {
// If the top of heap is less than the arr[i]
// then remove top element and insert arr[i]
if(minH.top() < arr[i]) {
minH.pop();
minH.push(arr[i]);
}
}
vector<int> res;
// Min heap will contain only k
// largest element
while (!minH.empty()) {
res.push_back(minH.top());
minH.pop();
}
// Reverse the result array, so that all
// elements are in decreasing order
reverse(res.begin(), res.end());
return res;}
int main() { vector arr = {1, 23, 12, 9, 30, 2, 50}; int k = 3;
vector<int> res = kLargest(arr, k);
for(int ele : res)
cout << ele << " ";
return 0;}
Java
// Java program to find the k largest elements in the
// array using min heap
import java.util.*;
class GfG {
// Function to find the k largest elements in the array
static ArrayList<Integer> kLargest(int[] arr, int k) {
// Min-heap to store the k largest elements
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
// Add first k elements to the heap
for (int i = 0; i < k; i++) {
minHeap.add(arr[i]);
}
// Traverse the rest of the array
for (int i = k; i < arr.length; i++) {
// If current element is larger than
// the smallest in heap
if (arr[i] > minHeap.peek()) {
minHeap.poll();
minHeap.add(arr[i]);
}
}
// Extract elements from the heap
ArrayList<Integer> res = new ArrayList<>();
while (!minHeap.isEmpty()) {
res.add(minHeap.poll());
}
// Reverse the list for descending order
Collections.reverse(res);
return res;
}
public static void main(String[] args) {
int[] arr = {1, 23, 12, 9, 30, 2, 50};
int k = 3;
ArrayList<Integer> res = kLargest(arr, k);
for (int ele : res) {
System.out.print(ele + " ");
}
}}
Python
Python program to find the k largest elements in the
array using min heap
import heapq
Function to find the k largest elements in the array
def kLargest(arr, k):
# Create a min-heap with the first k elements
minH = arr[:k]
heapq.heapify(minH)
# Traverse the rest of the array
for x in arr[k:]:
if x > minH[0]:
heapq.heapreplace(minH, x)
res = []
# Min heap will contain only k
# largest element
while minH:
res.append(heapq.heappop(minH))
# Reverse the result array, so that all
# elements are in decreasing order
res.reverse()
return resif name == "main": arr = [1, 23, 12, 9, 30, 2, 50] k = 3 res = kLargest(arr, k) print(" ".join(map(str, res)))
C#
// C# program to find the k largest elements in the
// array using min heap
using System; using System.Collections.Generic;
class GfG {
// Function to find the k largest elements in the array
static List<int> kLargest(int[] arr, int k) {
// Min-heap using a SortedSet
SortedSet<int> minH = new SortedSet<int>();
// Insert the first k elements into the min-heap
for (int i = 0; i < k; i++) {
minH.Add(arr[i]);
}
// Process the remaining elements
for (int i = k; i < arr.Length; i++) {
// If the current element is larger
// than the smallest in the heap
if (arr[i] > minH.Min) {
minH.Remove(minH.Min);
minH.Add(arr[i]);
}
}
// Extract k largest elements from the heap
List<int> res = new List<int>(minH);
// Reverse the result array to get
// elements in decreasing order
res.Sort((a, b) => b.CompareTo(a));
return res;
}
static void Main() {
int[] arr = { 1, 23, 12, 9, 30, 2, 50 };
int k = 3;
List<int> res = kLargest(arr, k);
foreach (int ele in res)
Console.Write(ele + " ");
}}
JavaScript
//Driver Code Starts
// JavaScript program to find the k largest elements in the
// array using min heap
class MinHeap { constructor() { this.heap = []; }
// Swap two elements in the heap
swap(i, j) {
[this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
}
// Heapify up to maintain min heap property
heapifyUp() {
let index = this.heap.length - 1;
while (index > 0) {
let parentIndex = Math.floor((index - 1) / 2);
if (this.heap[parentIndex] <= this.heap[index]) break;
this.swap(parentIndex, index);
index = parentIndex;
}
}
// Heapify down to maintain min heap property
heapifyDown() {
let index = 0;
while (2 * index + 1 < this.heap.length) {
let leftChild = 2 * index + 1;
let rightChild = 2 * index + 2;
let smallest = leftChild;
if (rightChild < this.heap.length && this.heap[rightChild] < this.heap[leftChild]) {
smallest = rightChild;
}
if (this.heap[index] <= this.heap[smallest]) break;
this.swap(index, smallest);
index = smallest;
}
}
// Insert element into the min heap
push(val) {
this.heap.push(val);
this.heapifyUp();
}
// Remove and return the top element (smallest)
pop() {
if (this.heap.length === 1) return this.heap.pop();
let min = this.heap[0];
this.heap[0] = this.heap.pop();
this.heapifyDown();
return min;
}
// Get the top element (smallest)
top() {
return this.heap[0];
}
// Check if the heap is empty
empty() {
return this.heap.length === 0;
}} //Driver Code Ends
// Function to find the k largest elements in the array function kLargest(arr, k) {
// Min Priority Queue (Min-Heap) with first k
// elements of the array
let minH = new MinHeap();
for (let i = 0; i < k; i++) {
minH.push(arr[i]);
}
// Traverse n - k elements
for (let i = k; i < arr.length; i++) {
// If the top of heap is less than the arr[i]
// then remove top element and insert arr[i]
if (minH.top() < arr[i]) {
minH.pop();
minH.push(arr[i]);
}
}
let res = [];
// Min heap will contain only k
// largest elements
while (!minH.empty()) {
res.push(minH.pop());
}
// Reverse the result array, so that all
// elements are in decreasing order
res.reverse();
return res;}
//Driver Code Starts // Driver Code let arr = [1, 23, 12, 9, 30, 2, 50]; let k = 3;
let res = kLargest(arr, k); console.log(res.join(" "));
//Driver Code Ends
`
**Time Complexity: O(n * log k), this solution can work in O(k + (n-k) Log K) as build heap take linear time.
**Auxiliary Space: O(k)
**Note: JavaScript does not seem to support min heap in native implementation, so it is recommended to use Quick Select implementation.
[Alternate Approach] Using Quick Select algorithm
The idea is to use the **partitioning step of QuickSort to find the k largest elements in the array, without sorting the entire array. When sorting the element in the **descending order, the partitioning step **rearranges the elements in a way that all elements greater than or equal to a chosen pivot (usually the last element) are placed on its left, and all elements lesser than the pivot are on its right. And pivot element in its **correct sorted position.
After each partition, we compare the **number of elements in the leftpart of the array (which contains all elements greater than or equal to the pivot) with k:
- **Number of elements in the left = k, it means all elements in the left part (including pivot) are the k largest elements.
- **Number of elements in the left > k, it means that k largest elements exist in the left subarray only, so we recursively search in the left subarray.
- **Number of elements in the left < k, it means that the k largest elements include the entire left part of the array along with some elements from the right part. Therefore we reduce k by the number of elements already covered on the left side and search in the right subarray.
C++ `
// C++ program to find the k largest elements in the array // using partitioning step of quick sort
#include #include #include using namespace std;
// Function to partition the array around a pivot int partition(vector &arr, int left, int right) {
// Last element is chosen as a pivot.
int pivot = arr[right];
int i = left;
for (int j = left; j < right; j++) {
// Elements greater than or equal to pivot
// are placed in the left side of pivot
if (arr[j] >= pivot) {
swap(arr[i], arr[j]);
i++;
}
}
swap(arr[i], arr[right]);
// The correct sorted position of the pivot
return i;}
void quickSelect(vector &arr, int left, int right, int k) { if (left <= right) { int pivotIdx = partition(arr, left, right);
// Count of all elements in the left part
int leftCnt = pivotIdx - left + 1;
// If leftCnt is equal to k, then we have
// found the k largest element
if (leftCnt == k)
return;
// Search in the left subarray
if (leftCnt > k)
quickSelect(arr, left, pivotIdx - 1, k);
// Reduce the k by number of elements already covered
// and search in the right subarray
else
quickSelect(arr, pivotIdx + 1, right, k - leftCnt);
}}
vector kLargest(vector &arr, int k) { int n = arr.size(); quickSelect(arr, 0, n - 1, k);
// First k elements of the array will be the largest
vector<int> res(arr.begin(), arr.begin() + k);
// Sort the result in descending order
sort(res.begin(), res.end(), greater<int>());
return res;}
int main() { vector arr = {1, 23, 12, 9, 30, 2, 50}; int k = 3;
vector<int> res = kLargest(arr, k);
for (int ele : res)
cout << ele << " ";
return 0;}
Java
// Java program to find the k largest elements in the array // using partitioning step of quick sort
import java.util.*;
class GfG {
// Function to partition the array around a pivot
static int partition(int[] arr, int left, int right) {
// Last element is chosen as a pivot.
int pivot = arr[right];
int i = left;
for (int j = left; j < right; j++) {
// Elements greater than or equal to pivot
// are placed in the left side of pivot
if (arr[j] >= pivot) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
}
}
int temp = arr[i];
arr[i] = arr[right];
arr[right] = temp;
// The correct sorted position of the pivot
return i;
}
static void quickSelect(int[] arr, int left, int right, int k) {
if (left <= right) {
int pivotIdx = partition(arr, left, right);
// Count of all elements in the left part
int leftCnt = pivotIdx - left + 1;
// If leftCnt is equal to k, then we have
// found the k largest element
if (leftCnt == k)
return;
// Search in the left subarray
if (leftCnt > k)
quickSelect(arr, left, pivotIdx - 1, k);
// Reduce the k by number of elements already covered
// and search in the right subarray
else
quickSelect(arr, pivotIdx + 1, right, k - leftCnt);
}
}
static ArrayList<Integer> kLargest(int[] arr, int k) {
quickSelect(arr, 0, arr.length - 1, k);
ArrayList<Integer> res = new ArrayList<>();
// First k elements of the array, will be the largest
for(int i = 0; i < k; i++)
res.add(arr[i]);
// Sort the result in descending order
Collections.sort(res, Collections.reverseOrder());
return res;
}
public static void main(String[] args) {
int[] arr = {1, 23, 12, 9, 30, 2, 50};
int k = 3;
ArrayList<Integer> res = kLargest(arr, k);
for (int ele : res)
System.out.print(ele + " ");
}}
Python
Python program to find the k largest elements in the array
using partitioning step of quick sort
Function to partition the array around a pivot
def partition(arr, left, right):
# Last element is chosen as a pivot.
pivot = arr[right]
i = left
for j in range(left, right):
# Elements greater than or equal to pivot
# are placed in the left side of pivot
if arr[j] >= pivot:
arr[i], arr[j] = arr[j], arr[i]
i += 1
arr[i], arr[right] = arr[right], arr[i]
# The correct sorted position of the pivot
return idef quickSelect(arr, left, right, k): if left <= right: pivotIdx = partition(arr, left, right)
# Count of all elements in the left part
leftCnt = pivotIdx - left + 1
# If leftCnt is equal to k, then we have
# found the k largest element
if leftCnt == k:
return
# Search in the left subarray
if leftCnt > k:
quickSelect(arr, left, pivotIdx - 1, k)
# Reduce the k by number of elements already covered
# and search in the right subarray
else:
quickSelect(arr, pivotIdx + 1, right, k - leftCnt)def kLargest(arr, k): quickSelect(arr, 0, len(arr) - 1, k)
# First k elements of the array, will be the largest
res = arr[:k]
# Sort the result in descending order
res.sort(reverse=True)
return resif name == "main": arr = [1, 23, 12, 9, 30, 2, 50] k = 3 res = kLargest(arr, k) print(" ".join(map(str, res)))
C#
// C# program to find the k largest elements in the array // using partitioning step of quick sort
using System; using System.Collections.Generic;
class GfG {
// Function to partition the array around a pivot
static int partition(int[] arr, int left, int right) {
// Last element is chosen as a pivot.
int pivot = arr[right];
int i = left;
for (int j = left; j < right; j++) {
// Elements greater than or equal to pivot
// are placed in the left part of pivot
if (arr[j] >= pivot) {
swap(arr, i, j);
i++;
}
}
swap(arr, i, right);
// The correct sorted position of the pivot
return i;
}
static void quickSelect(int[] arr, int left, int right, int k) {
if (left <= right) {
int pivotIdx = partition(arr, left, right);
// Count of all elements in the left part
int leftCnt = pivotIdx - left + 1;
// If leftCnt is equal to k, then we have
// found the k largest element
if (leftCnt == k)
return;
// Search in the left subarray
if (leftCnt > k)
quickSelect(arr, left, pivotIdx - 1, k);
// Reduce the k by number of elements already covered
// and search in the right subarray
else
quickSelect(arr, pivotIdx + 1, right, k - leftCnt);
}
}
static List<int> kLargest(int[] arr, int k) {
quickSelect(arr, 0, arr.Length - 1, k);
// First k elements of the array will be the largest
List<int> res = new List<int>();
for (int i = 0; i < k; i++) {
res.Add(arr[i]);
}
// Sort the list in descending order
res.Sort((a, b) => b.CompareTo(a));
return res;
}
static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
static void Main() {
int[] arr = {1, 23, 12, 9, 30, 2, 50};
int k = 3;
List<int> res = kLargest(arr, k);
foreach (int ele in res)
Console.Write(ele + " ");
}}
JavaScript
// JavaScript program to find the k largest elements in the array // using partitioning step of quick sort
// Function to partition the array around a pivot function partition(arr, left, right) {
// Last element is chosen as a pivot.
let pivot = arr[right];
let i = left;
for (let j = left; j < right; j++) {
// Elements greater than or equal to pivot are
// placed in the left part of pivot
if (arr[j] >= pivot) {
[arr[i], arr[j]] = [arr[j], arr[i]];
i++;
}
}
[arr[i], arr[right]] = [arr[right], arr[i]];
// The correct sorted position of the pivot
return i;}
function quickSelect(arr, left, right, k) { if (left <= right) { let pivotIdx = partition(arr, left, right);
// Count of all elements in the left part
let leftCnt = pivotIdx - left + 1;
// If leftCnt is equal to k, then the first
// k element of the array will be largest
if (leftCnt === k)
return;
// Search in the left subarray
if (leftCnt > k)
quickSelect(arr, left, pivotIdx - 1, k);
// Reduce the k by number of elements already covered
// and search in the right subarray
else
quickSelect(arr, pivotIdx + 1, right, k - leftCnt);
}}
function kLargest(arr, k) { quickSelect(arr, 0, arr.length - 1, k);
// First k elements of the array, will be the largest
let res = arr.slice(0, k);
// Sort the first k elements in descending order
res.sort((a, b) => b - a);
return res;}
// Driver Code const arr = [1, 23, 12, 9, 30, 2, 50]; const k = 3; const res = kLargest(arr, k); console.log(res.join(' '));
`
**Time Complexity: O(n2) in worst case (O(n) on average).
**Auxiliary Space: O(n)