Question: Write an efficient program for printing k largest elements in an array. Elements in array can be in any order.
For example, if given array is [1, 23, 12, 9, 30, 2, 50] and you are asked for the largest 3 elements i.e., k = 3 then your program should print 50, 30 and 23.
Method 1 (Use Bubble k times)
Thanks to Shailendra for suggesting this approach.
1) Modify Bubble Sort to run the outer loop at most k times.
2) Print the last k elements of the array obtained in step 1.
Time Complexity: O(nk)
Like Bubble sort, other sorting algorithms like Selection Sort can also be modified to get the k largest elements.
Method 2 (Use temporary array)
K largest elements from arr[0..n-1]
1) Store the first k elements in a temporary array temp[0..k-1].
2) Find the smallest element in temp[], let the smallest element be min.
3-a) For each element x in arr[k] to arr[n-1]. O(n-k)
If x is greater than the min then remove min from temp[] and insert x.
3-b)Then, determine the new min from temp[]. O(k)
4) Print final k elements of temp[]
Time Complexity: O((n-k)*k). If we want the output sorted then O((n-k)*k + klogk)
Thanks to nesamani1822 for suggesting this method.
Method 3(Use Sorting)
1) Sort the elements in descending order in O(nLogn)
2) Print the first k numbers of the sorted array O(k).
Following is the implementation of the above.
C++
// C++ code for k largest elements in an array #include <bits/stdc++.h> using namespace std; void kLargest( int arr[], int n, int k) { // Sort the given array arr in reverse // order. sort(arr, arr + n, greater< int >()); // Print the first kth largest elements for ( int i = 0; i < k; i++) cout << arr[i] << " " ; } // driver program int main() { int arr[] = { 1, 23, 12, 9, 30, 2, 50 }; int n = sizeof (arr) / sizeof (arr[0]); int k = 3; kLargest(arr, n, k); } // This article is contributed by Chhavi |
Java
// Java code for k largest elements in an array import java.util.Arrays; import java.util.Collections; class GFG { public static void kLargest(Integer[] arr, int k) { // Sort the given array arr in reverse order // This method doesn't work with primitive data // types. So, instead of int, Integer type // array will be used Arrays.sort(arr, Collections.reverseOrder()); // Print the first kth largest elements for ( int i = 0 ; i < k; i++) System.out.print(arr[i] + " " ); } public static void main(String[] args) { Integer arr[] = new Integer[] { 1 , 23 , 12 , 9 , 30 , 2 , 50 }; int k = 3 ; kLargest(arr, k); } } // This code is contributed by Kamal Rawal |
Python
''' Python3 code for k largest elements in an array''' def kLargest(arr, k): # Sort the given array arr in reverse # order. arr.sort(reverse = True ) # Print the first kth largest elements for i in range (k): print (arr[i], end = " " ) # Driver program arr = [ 1 , 23 , 12 , 9 , 30 , 2 , 50 ] # n = len(arr) k = 3 kLargest(arr, k) # This code is contributed by shreyanshi_arun. |
C#
// C# code for k largest elements in an array using System; class GFG { public static void kLargest( int [] arr, int k) { // Sort the given array arr in reverse order // This method doesn't work with primitive data // types. So, instead of int, Integer type // array will be used Array.Sort(arr); Array.Reverse(arr); // Print the first kth largest elements for ( int i = 0; i < k; i++) Console.Write(arr[i] + " " ); } // Driver code public static void Main(String[] args) { int [] arr = new int [] { 1, 23, 12, 9, 30, 2, 50 }; int k = 3; kLargest(arr, k); } } // This code contributed by Rajput-Ji |
PHP
<?php // PHP code for k largest // elements in an array function kLargest(& $arr , $n , $k ) { // Sort the given array arr // in reverse order. rsort( $arr ); // Print the first kth // largest elements for ( $i = 0; $i < $k ; $i ++) echo $arr [ $i ] . " " ; } // Driver Code $arr = array (1, 23, 12, 9, 30, 2, 50); $n = sizeof( $arr ); $k = 3; kLargest( $arr , $n , $k ); // This code is contributed // by ChitraNayal ?> |
Output:
50 30 23
Time complexity: O(nlogn)
Method 4 (Use Max Heap)
1) Build a Max Heap tree in O(n)
2) Use Extract Max k times to get k maximum elements from the Max Heap O(klogn)
Time complexity: O(n + klogn)
Method 5(Use Oder Statistics)
1) Use order statistic algorithm to find the kth largest element. Please see the topic selection in worst-case linear time O(n)
2) Use QuickSort Partition algorithm to partition around the kth largest number O(n).
3) Sort the k-1 elements (elements greater than the kth largest element) O(kLogk). This step is needed only if sorted output is required.
Time complexity: O(n) if we don’t need the sorted output, otherwise O(n+kLogk)
Thanks to Shilpi for suggesting the first two approaches.
Method 6 (Use Min Heap)
This method is mainly an optimization of method 1. Instead of using temp[] array, use Min Heap.
1) Build a Min Heap MH of the first k elements (arr[0] to arr[k-1]) of the given array. O(k)
2) For each element, after the kth element (arr[k] to arr[n-1]), compare it with root of MH.
……a) If the element is greater than the root then make it root and call heapify for MH
……b) Else ignore it.
// The step 2 is O((n-k)*logk)
3) Finally, MH has k largest elements and root of the MH is the kth largest element.
Time Complexity: O(k + (n-k)Logk) without sorted output. If sorted output is needed then O(k + (n-k)Logk + kLogk)
All of the above methods can also be used to find the kth largest (or smallest) element.
C++
#include <iostream> using namespace std; // Swap function to interchange // the value of variables x and y int swap( int & x, int & y) { int temp = x; x = y; y = temp; } // Min Heap Class // arr holds reference to an integer // array size indicate the number of // elements in Min Heap class MinHeap { int size; int * arr; public : // Constructor to initialize the size and arr MinHeap( int size, int input[]); // Min Heapify function, that assumes that // 2*i+1 and 2*i+2 are min heap and fix the // heap property for i. void heapify( int i); // Build the min heap, by calling heapify // for all non-leaf nodes. void buildHeap(); }; // Constructor to initialize data // members and creating mean heap MinHeap::MinHeap( int size, int input[]) { // Initializing arr and size this ->size = size; this ->arr = input; // Building the Min Heap buildHeap(); } // Min Heapify function, that assumes // 2*i+1 and 2*i+2 are min heap and // fix min heap property for i void MinHeap::heapify( int i) { // If Leaf Node, Simply return if (i >= size / 2) return ; // variable to store the smallest element // index out of i, 2*i+1 and 2*i+2 int smallest; // Index of left node int left = 2 * i + 1; // Index of right node int right = 2 * i + 2; // Select minimum from left node and // current node i, and store the minimum // index in smallest variable smallest = arr[left] < arr[i] ? left : i; // If right child exist, compare and // update the smallest variable if (right < size) smallest = arr[right] < arr[smallest] ? right : smallest; // If Node i violates the min heap // property, swap current node i with // smallest to fix the min-heap property // and recursively call heapify for node smallest. if (smallest != i) { swap(arr[i], arr[smallest]); heapify(smallest); } } // Build Min Heap void MinHeap::buildHeap() { // Calling Heapify for all non leaf nodes for ( int i = size / 2 - 1; i >= 0; i--) { heapify(i); } } void FirstKelements( int arr[], int size, int k){ // Creating Min Heap for given // array with only k elements MinHeap* m = new MinHeap(k, arr); // Loop For each element in array // after the kth element for ( int i = k; i < size; i++) { // if current element is smaller // than minimum element, do nothing // and continue to next element if (arr[0] > arr[i]) continue ; // Otherwise Change minimum element to // current element, and call heapify to // restore the heap property else { arr[0] = arr[i]; m->heapify(0); } } // Now min heap contains k maximum // elements, Iterate and print for ( int i = 0; i < k; i++) { cout << arr[i] << " " ; } } // Driver Program int main() { int arr[] = { 11, 3, 2, 1, 15, 5, 4, 45, 88, 96, 50, 45 }; int size = sizeof (arr) / sizeof (arr[0]); // Size of Min Heap int k = 3; FirstKelements(arr,size,k); return 0; } // This code is contributed by Ankur Goel |
Java
import java.io.*; import java.util.*; class GFG{ public static void FirstKelements( int arr[], int size, int k) { // Creating Min Heap for given // array with only k elements // Create min heap with priority queue PriorityQueue<Integer> minHeap = new PriorityQueue<>(); for ( int i = 0 ; i < k; i++) { minHeap.add(arr[i]); } // Loop For each element in array // after the kth element for ( int i = k; i < size; i++) { // If current element is smaller // than minimum ((top element of // the minHeap) element, do nothing // and continue to next element if (minHeap.peek() > arr[i]) continue ; // Otherwise Change minimum element // (top element of the minHeap) to // current element by polling out // the top element of the minHeap else { minHeap.poll(); minHeap.add(arr[i]); } } // Now min heap contains k maximum // elements, Iterate and print Iterator iterator = minHeap.iterator(); while (iterator.hasNext()) { System.out.print(iterator.next() + " " ); } } // Driver code public static void main (String[] args) { int arr[] = { 11 , 3 , 2 , 1 , 15 , 5 , 4 , 45 , 88 , 96 , 50 , 45 }; int size = arr.length; // Size of Min Heap int k = 3 ; FirstKelements(arr, size, k); } } // This code is contributed by Vansh Sethi |
50 88 96
Please write comments if you find any of the above explanations/algorithms incorrect, or find better ways to solve the same problem.
References:
http://en.wikipedia.org/wiki/Selection_algorithm
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.