简体   繁体   English

获取数组中最大3个元素的最有效方法

[英]Most efficient way to get the largest 3 elements of an array

I have been given an array of elements and an inbuilt function which can sort 5 elements at a time. 我得到了一个元素数组和一个内置函数,该函数可以一次对5个元素进行排序。 How do I use only this function to obtain the largest 3 elements of the array with the least number of calls to this function? 如何仅使用此函数来获取数组的最大3个元素,且对该函数的调用次数最少?

The approach I have tried is dividing the array in groups of 5 each, applying the function on each group, and applying the function on the maximums obtained from each group. 我尝试过的方法是将数组分成5组,将函数应用于每个组,并将函数应用于从每个组获得的最大值。

This approach fails when the highest and second highest happen to be present in the same group. 当最高和次最高的碰巧出现在同一组中时,此方法将失败。 Is there a better approach to do this? 有没有更好的方法可以做到这一点?

Since you have the built-in method to sort five elements I suggest: Sort the first five elements from the array. 由于您具有对五个元素进行排序的内置方法,因此我建议:对数组中的前五个元素进行排序。 Repeatedly discard the two smallest of the five and replace with two more elements from the array (two elements that have not yet been considered), then sort the five again. 重复丢弃五个中最小的两个,并用数组中另外两个元素(尚未考虑的两个元素)替换,然后再次对五个排序。 In the end take the largest three of the five. 最后采取五个中最大的三个。

It will be possible to do a bit better than what I have sketched. 可能会比我所概述的做得更好。 Say you have 25 elements. 假设您有25个元素。 For each group of 5 find the three largest. 对于每5个一组,找到三个最大的组。 Then among the nos. 然后在nos之间。 1 from each group find the three largest. 从每组1个中找到三个最大的。 The same for the nos. 否也一样。 2 from each group and the nos. 每组2个,第2个。 3. Now we can deduce that the three largest overall will be among the three largest nos. 3.现在我们可以推断出三个最大的总数将在三个最大的否定之中。 1, the two largest nos. 1,两个最大的号码。 2 and the single largest no. 2和最大单号。 3, that is six elements instead of 9. So we can find the three largest in just two more calls to your built-in method instead of three more calls. 3,是六个元素,而不是9。因此,在对内置方法的另外两个调用中,而不是三个调用中,我们可以找到三个最大的元素。 Generalizing the idea to any size of the original array will be complicated, though. 但是,将思想推广到原始数组的任何大小都会很复杂。

How about this method. 这个方法怎么样。

  1. Divide the array into groups of 5 将数组分成5组
  2. Apply the provided sort method for each group of 5 elements 将提供的排序方法应用于每组5个元素
  3. Get the first 3 elements from each array 从每个数组中获取前3个元素
  4. Then merge the identified 3 elements in each group to one single array 然后将每组中确定的3个元素合并为一个数组
  5. Now repeat from step 1 to 4, until the final array size is less than or equal to 5 现在从步骤1到4重复,直到最终数组的大小小于或等于5
  6. Get the first 3 elements from the final array 从最终数组中获取前3个元素
#include <iostream>


void sortThree(int res[3]) {
   for(int j = 0; j < 2; j++) {
      if(res[j] > res[j+1])
         std::swap(res[j], res[j+1]);
}
   if(res[0] > res[1]) std::swap(res[0], res[1]); // second pass
}

bool lsearch(int src[], int n, int k) {
  for(int i = 0; i < n; i++) {
    if(src[i] == k) return true;
  }
  return false;
}

void getThreeLargest(int arr[], int n, int res[3]) {
  res[0] = arr[0];
  res[1] = arr[1];
  res[2] = arr[2];
  sortThree(res);
  for(int i = 3; i < n; i++) {
    // if no repetition wanted
    // if(arr[i] > res[0] && !lsearch(res, 3, arr[i])) {
    if(arr[i] > res[0]) {
      res[0] = arr[i];
      sortThree(res);
    }
  }
}

int main(int argc, char *argv[])
{
  int arr[] = {91,21,3,-4,5,2,1,90,9,11};
  int res[3];
  getThreeLargest(arr, 10, res);
  for(int i = 0; i < 3; i++)
    std::cout << res[i] << '\n';
  return 0;
}

Very simple solution here in a c-way to do it. 这里非常简单的解决方案以C方式实现。 You can easily convert it to java. 您可以轻松地将其转换为Java。 Scanning the array is O(n). 扫描阵列为O(n)。 Since the little array to be sorted and searched has only 3 elements we can easily use linear search to avoid repetition and sorting takes only 2 comparisons. 由于要排序和搜索的小数组只有3个元素,因此我们可以轻松地使用线性搜索来避免重复,排序仅需进行2个比较。 It's still O(n). 仍然是O(n)。

#include<stdio.h>
#include<limits.h>

int retmax(int *a,int n,int exc){

    int max = INT_MIN;
    for(int i=0;i<n;i++){
        if(a[i] > max && a[i] < exc)
           max = a[i];
    }

    return max;
}

int main(){

    int a[]={32,54,12,43,98,45,87};
    int size = sizeof(a)/sizeof(a[0]);

    int x = retmax(a,size,INT_MAX);
    int y = retmax(a,size,x);
    int z = retmax(a,size,y);

    printf("%d %d %d",x,y,z);
}

A simple O(n) solution. 一个简单的O(n)解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 根据元素频率对数组元素进行排序的最有效方法是什么 - Whats the most efficient way to sort elements of an array based on frequency of elements 将元素从多维数组复制到平面数组的最有效方法? - Most efficient way to copy elements from multidimensional array to flat array? 从数组中删除连续元素的最有效方法? 爪哇 - Most efficient way to remove consectuive elements from an array? Java 在Java中获取k个最小(或最大)数组元素的最快方法是什么? - What is the fastest way to get k smallest (or largest) elements of array in Java? 这是初始化数组的最有效方法 - Is this the most efficient way to initialize an array 获取数组列表Java中前k项的最有效方法 - Most efficient way to get top k items in an array list Java Java:获取输入整数数组的最有效方法 - Java: Most Efficient Way to Get Input Integer Array 给定一个原始数组 Object,确定数组元素原始类型的最有效方法是什么 - Given an Object that is a primitive array, what is the most efficient way to determine the primitive type of the array elements 找到最大的总和,包括阵列中最多两个连续元素 - Find the largest sum including at most two consecutive elements from an array Java - 从Array []中删除一组元素的最有效方法是什么 - Java - What's the most efficient way of removing a set of elements from an Array[]
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM