【问题标题】:Algorithm to find sum of 2nd,3rd and 4th highest numbers from 2 different arrays从 2 个不同数组中查找第 2、第 3 和第 4 大数字之和的算法
【发布时间】:2011-09-19 19:07:22
【问题描述】:

我有 2 个非常大的整数数组,比如 a[] 和 b[]。
我想从 a[] 和 b[] 中计算第二、第三和第四大数字的总和。 即两个数组中的第 2、第 3 和第 4 大数字......这是只有 3 个数字的总和。 请为这个问题提出一个好的算法。

考虑到算法的时间复杂度,请支持您的回答。

注意:编程语言不是问题。你可以假设 C

这是我针对这个问题开发的
算法:
1. 考虑数组 a[] 和 b[]。使用最大堆排序对 a[] 和 b[] 进行排序。
2. 两个数组现在都以最大元素作为两个数组中的根节点进行排序。比较 a[] 和 b[] 的根节点,取较大者,从数组中删除那个数。
3. 重新堆放具有最大元素的数组。
4. 现在将 a[] 和 b[] 的根节点添加到变量 sum 中。
5. 重新堆化 a[] 和 b[]。
6. 比较 a[] 和 b[] 的根节点,以较大者相加。
7. 打印变量总和。

【问题讨论】:

  • 对这个问题有什么你的想法?
  • 这看起来像是典型的给我一个答案-for-my-homework-question。
  • 你可以创建另一个数组 c[],按降序排序,然后返回 c[1] + c[2] + c[3]。我认为没有比这更有效率的了。
  • 您无需排序即可获得最高的 4 个数字
  • @TomalakGeret'kal 和 downvoters:这个问题是否因为它看起来像家庭作业或其他原因而收到与它一样多的反对票?如果是因为它看起来像家庭作业,我应该注意这种类型的问题不是一些深奥的,仅限于家庭作业类型的问题。我以前需要在专业环境中完成非常相似的任务。

标签: arrays algorithm data-structures


【解决方案1】:

由于数组没有排序,你必须至少遍历每个数字一次,所以你有一个 O(n) 的下限,其中 n 是数字的总数。我相信你可以在 O(n) 内完成。

时间:O(n)

空格:O(1)

int sum = 0;
int no1 = 0;
int no2 = 0;
int no3 = 0;
int no4 = 0;

int n =  a.size();

for ( int i = 0 ; i < n ; i++ )
{
   if ( a[i] >= no1 )
   {
      no4 = no3; no3 = no2; no2 = no1; no1 = a[i];
   }
   else if ( a[i] >= no2 )
   {
      no4 = no3; no3 = no2; no2 = a[i];
   }
   else if ( a[i] >= no3 )
   {
      no4 = no3; no3 = a[i];
   }
   else if ( a[i] > no4 )
   {
      no4 = a[i];
   } 
}

// Repeat the n =  a[].lenght; for ( int i = 0 ; i < n ; i++ ){...}
// but using the b[] array instead of the a[]

sum = no2 + no3 + no4;

排序是低效的,因为你只需要 3 个数字,那为什么还要额外的工作呢?

【讨论】:

  • 这适用于您想要 3 个选择但不能很好概括的特定情况。此外,如果选择的数量变得不平凡,则复杂性可能与 n 成线性关系。
  • @Luchian Grigore 你没有考虑有 2 个数组的事实......这仅适用于 1 个数组
  • 只是补充说他有两个数组,你必须遍历 2 个数组。
  • 我投反对票的原因很简单,因为我认为这不是一个好的答案,因为存在更好、更简单和更明显的答案。您投反对票的原因是我的不能一概而论。但这不是重点,因为对于手头的问题,它比您的解决方案要好。否决比你更好的解决方案有点苛刻,你不是说吗?
  • @Luchian 我引用的选择算法可以在 O(n + k log k) 中完成,其中 k 个事物被选择。对于 k=3,可以忽略不计。问题所要求的正是一个选择算法,所以我认为对一个提到选择算法的答案投反对票是很苛刻的。
【解决方案2】:

O(n) 在 python 中:

def biggestn(n, array):
   arr=[]
   for x in array:
      arr=insert(arr,x)[0:n] #use insertion sort to insert x into arr here for speed 
   return sum(arr)

对于两个数组只需biggestn(4, a++b)

【讨论】:

  • 当您说O(n) 时,n 是指数组的长度还是您使用的实际n?从技术上讲,它取决于两者,但在这里应该可以忽略不计,因为 OP 只指定了 3 个元素。
  • 是的,我的意思是数组的长度。应该是 O(mlogn),其中 n 是这里使用的 n i,m 是数组的长度。
  • 你需要看看你是否应该保留它,因此你需要排序(例如,将它与其他数字进行比较)。这有点等同于@Lucians 的答案,但可以推广到任何整数。插入排序只有O(logn) 插入时间,对于n=4 应该考虑O(1)。就像我现在所做的那样,可以很容易地用 insert 替换它。
【解决方案3】:

天真的解决方案(我不推荐)是先排序,然后添加 3 个元素。假设一个合理的排序算法,这将是O(n*log(n))

推广到 3 个以上元素的更好解决方案是基于选择排序或快速排序实现多个 selection algorithms 之一。根据具体想要做什么,这些可以接近线性时间。

【讨论】:

  • 这取决于您是否要概括为 3 个以上的选择。
  • 如果您只想从中选择3个数字,则不需要对数组进行排序。
  • @woliveirajr 我不是建议你排序;我提到过这种方式是一个坏主意。无论如何,如果您概括以上 3,那么您需要一个选择算法。
猜你喜欢
  • 2020-06-18
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 2021-05-14
  • 1970-01-01
  • 2018-09-20
  • 1970-01-01
相关资源
最近更新 更多