问题:编写一个有效的程序来打印数组中k个最大的元素。数组中的元素可以按任何顺序排列。
例如,如果给定的数组为[1、23、12、9、30、2、50],并且要求您输入最大的3个元素,即k = 3,则您的程序应打印50、30和23。
方法1(使用泡泡k次)
感谢Shailendra提出了这种方法。
1)修改气泡排序以最多运行k次外部循环。
2)打印在步骤1中获得的数组的最后k个元素。
时间复杂度:O(nk)
像冒泡排序一样,其他排序算法(例如选择排序)也可以修改以获取k个最大元素。
方法2(使用临时数组)
来自arr [0..n-1]的K个最大元素
1)将前k个元素存储在临时数组temp [0..k-1]中。
2)在temp []中找到最小的元素,让最小的元素为min 。
3-a)对于arr [k]至arr [n-1]中的每个元素x 。 O(nk)
如果x大于min,则从temp []中删除min并插入x 。
3-b)然后,从temp []确定新的分钟。好的)
4)打印temp的最后k个元素
时间复杂度:O((nk)* k)。如果我们要对输出进行排序,则O((nk)* k + klogk)
感谢nesamani1822建议使用此方法。
方法3(使用排序)
1)在O(nLogn)中按降序对元素进行排序
2)打印排序后的数组O(k)的前k个数字。
以下是上述的实现。
C++
// C++ code for k largest elements in an array
#include
using namespace std;
void kLargest(int arr[], int n, int k)
{
// Sort the given array arr in reverse
// order.
sort(arr, arr + n, greater());
// 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;
import java.util.ArrayList;
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] + " ");
}
//This code is contributed by Niraj Dubey
public static ArrayList kLargest(int[] arr, int k)
{
//Convert using stream
Integer[] obj_array = Arrays.stream( arr ).boxed().toArray( Integer[] :: new);
Arrays.sort(obj_array, Collections.reverseOrder());
ArrayList list = new ArrayList<>(k);
for (int i = 0; i < k; i++)
list.add(obj_array[i]);
return list;
}
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 Niraj Dubey
//What if primitive datatype array is passed and wanted to return in ArrayList
int[] prim_array = { 1, 23, 12, 9, 30, 2, 50 };
System.out.print(kLargest(prim_array, 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
C++
#include
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 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
Python3
def FirstKelements(arr,size,k):
# Creating Min Heap for given
# array with only k elements
# Create min heap with priority queue
minHeap = []
for i in range(k):
minHeap.append(arr[i])
# Loop For each element in array
# after the kth element
for i in range(k, size):
minHeap.sort()
# If current element is smaller
# than minimum ((top element of
# the minHeap) element, do nothing
# and continue to next element
if (minHeap[0] > 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.pop(0)
minHeap.append(arr[i])
# Now min heap contains k maximum
# elements, Iterate and print
for i in minHeap:
print(i, end = " ")
# Driver code
arr=[11, 3, 2, 1, 15, 5, 4,45, 88, 96, 50, 45]
size = len(arr)
# Size of Min Heap
k=3
FirstKelements(arr, size, k)
# This code is contributed by avanitrachhadiya2155
C#
using System;
using System.Collections.Generic;
public 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
List minHeap = new List();
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++)
{
minHeap.Sort();
// If current element is smaller
// than minimum ((top element of
// the minHeap) element, do nothing
// and continue to next element
if (minHeap[0] > 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.RemoveAt(0);
minHeap.Add(arr[i]);
}
}
// Now min heap contains k maximum
// elements, Iterate and print
foreach (int i in minHeap)
{
Console.Write(i + " ");
}
}
// 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 aashish1995.
C++
#include
using namespace std;
int findPivot(int a[], int start, int end)
{
// Selecting the pivot element
int pivot = a[end];
// Initially partition-index will be
// at starting
int pIndex = start;
for (int i = start; i < end; i++) {
// If an element is lesser than pivot, swap it.
if (a[i] <= pivot) {
swap(a[i], a[pIndex]);
// Incrementing pIndex for further
// swapping.
pIndex++;
}
}
// Lastly swapping or the
// correct position of pivot
swap(a[pIndex], a[end]);
return pIndex;
}
void SmallestLargest(int a[], int low, int high, int k,
int n)
{
if (low == high)
return;
else {
int pivotIndex = findPivot(a, low, high);
if (k == pivotIndex) {
cout << k << " smallest elements are : ";
for (int i = 0; i < pivotIndex; i++)
cout << a[i] << " ";
cout << endl;
cout << k << " largest elements are : ";
for (int i = (n - pivotIndex); i < n; i++)
cout << a[i] << " ";
}
else if (k < pivotIndex)
SmallestLargest(a, low, pivotIndex - 1, k, n);
else if (k > pivotIndex)
SmallestLargest(a, pivotIndex + 1, high, k, n);
}
}
// Driver Code
int main()
{
int a[] = { 11, 3, 2, 1, 15, 5, 4, 45, 88, 96, 50, 45 };
int n = sizeof(a) / sizeof(a[0]);
int low = 0;
int high = n - 1;
// Lets assume k is 3
int k = 3;
// Function Call
SmallestLargest(a, low, high, k, n);
return 0;
}
50 30 23
时间复杂度: O(nlogn)
方法4(使用最大堆)
1)在O(n)中建立一个最大堆树
2)使用提取最大k次从最大堆O(klogn)中获取k个最大元素
时间复杂度: O(n + klogn)
方法5(使用订单统计)
1)使用顺序统计算法找到第k个最大元素。请参阅最坏情况的线性时间O(n)中的主题选择
2)使用QuickSort分区算法对第k个最大数O(n)进行分区。
3)对k-1个元素(大于第k个最大元素的元素)进行排序O(kLogk)。仅当需要排序的输出时才需要此步骤。
时间复杂度:如果不需要排序的输出,则为O(n),否则为O(n + kLogk)
感谢Shilpi提出了前两种方法。
方法6(使用最小堆)
此方法主要是方法1的优化。请使用Min Heap,而不要使用temp []数组。
1)建立给定数组的前k个元素(arr [0]至arr [k-1])的Min Heap MH。好的)
2)对于每个元素,在第k个元素(arr [k]至arr [n-1])之后,将其与MH的根进行比较。
……a)如果元素大于根,则将其设为根并为MH调用heapify
……b)否则忽略它。
//步骤2为O((nk)* logk)
3)最后,MH具有k个最大元素,并且MH的根是第k个最大元素。
时间复杂度:无排序输出的O(k +(nk)Logk)。如果需要排序的输出,则O(k +(nk)Logk + kLogk)
所有上述方法也可以用于找到第k个最大(或最小)元素。
C++
#include
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 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
Python3
def FirstKelements(arr,size,k):
# Creating Min Heap for given
# array with only k elements
# Create min heap with priority queue
minHeap = []
for i in range(k):
minHeap.append(arr[i])
# Loop For each element in array
# after the kth element
for i in range(k, size):
minHeap.sort()
# If current element is smaller
# than minimum ((top element of
# the minHeap) element, do nothing
# and continue to next element
if (minHeap[0] > 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.pop(0)
minHeap.append(arr[i])
# Now min heap contains k maximum
# elements, Iterate and print
for i in minHeap:
print(i, end = " ")
# Driver code
arr=[11, 3, 2, 1, 15, 5, 4,45, 88, 96, 50, 45]
size = len(arr)
# Size of Min Heap
k=3
FirstKelements(arr, size, k)
# This code is contributed by avanitrachhadiya2155
C#
using System;
using System.Collections.Generic;
public 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
List minHeap = new List();
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++)
{
minHeap.Sort();
// If current element is smaller
// than minimum ((top element of
// the minHeap) element, do nothing
// and continue to next element
if (minHeap[0] > 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.RemoveAt(0);
minHeap.Add(arr[i]);
}
}
// Now min heap contains k maximum
// elements, Iterate and print
foreach (int i in minHeap)
{
Console.Write(i + " ");
}
}
// 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 aashish1995.
50 88 96
方法6(使用快速排序分区算法):
- 选择一个枢纽号码。
- 如果K小于ivot_Index,则重复该步骤。
- 如果K == ivot_Index:打印数组(低旋转以获取K个最小元素,而(n-pivot_Index)到n个fo K个最大元素)
- 如果K> ivot_Index:对右侧部分重复上述步骤。
以下是上述算法的实现:
C++
#include
using namespace std;
int findPivot(int a[], int start, int end)
{
// Selecting the pivot element
int pivot = a[end];
// Initially partition-index will be
// at starting
int pIndex = start;
for (int i = start; i < end; i++) {
// If an element is lesser than pivot, swap it.
if (a[i] <= pivot) {
swap(a[i], a[pIndex]);
// Incrementing pIndex for further
// swapping.
pIndex++;
}
}
// Lastly swapping or the
// correct position of pivot
swap(a[pIndex], a[end]);
return pIndex;
}
void SmallestLargest(int a[], int low, int high, int k,
int n)
{
if (low == high)
return;
else {
int pivotIndex = findPivot(a, low, high);
if (k == pivotIndex) {
cout << k << " smallest elements are : ";
for (int i = 0; i < pivotIndex; i++)
cout << a[i] << " ";
cout << endl;
cout << k << " largest elements are : ";
for (int i = (n - pivotIndex); i < n; i++)
cout << a[i] << " ";
}
else if (k < pivotIndex)
SmallestLargest(a, low, pivotIndex - 1, k, n);
else if (k > pivotIndex)
SmallestLargest(a, pivotIndex + 1, high, k, n);
}
}
// Driver Code
int main()
{
int a[] = { 11, 3, 2, 1, 15, 5, 4, 45, 88, 96, 50, 45 };
int n = sizeof(a) / sizeof(a[0]);
int low = 0;
int high = n - 1;
// Lets assume k is 3
int k = 3;
// Function Call
SmallestLargest(a, low, high, k, n);
return 0;
}
3 smallest elements are : 3 2 1
3 largest elements are : 96 50 88