繁体   English   中英

给定一个大小的数组NI需要找到将在最小和最大范围内总和的最小值数

[英]Given an array of size N I need to find the min number of values that will sum up within a min and max range

给定一个大小的数组NI需要找到将在最小和最大范围内总和的最小值数。

例如:考虑一个数组[1,2,3,4,5]。 我需要从这个数组中找到最小数量的值,其总和大于5且小于8. Ans:因为1 + 5大于5且小于8所以最小值数为2因此答案。

下面是我实现逻辑的函数。

int void CheckValue()
{
 for (i = 0; i <5; i++)
    if (a[i] > min && a[i] < max)
       return 1;
 for (i = 0; i< 4; i++)
     for (j = i + 1; j < 5; j++)
         if (a[i] + a[j] > min && a[i] + a[j] < max)
            return 2;


  for (i = 0; i < 3; i++)
      for (j = i + 1; j < 4; j++)
          for (k = j+1; k < 5; k++)
              if (a[i] + a[j] + a[k] > min && a[i] + a[j] + a[k] < max) 
                 return 3;
  for (i = 0; i < 2; i++)
      for (j = i + 1; j< 3; j++)
          for (k = j + 1; k< 4; k++)
              for (l = k + 1; l < 5; l++)
                  if (a[i] + a[j] + a[k] + a[l] > min && a[i] + a[j] + a[k] + a[l] < max)
                     return 4;
  if(a[0]+a[1]+a[2]+a[3]+a[4]>min && a[0]+a[1]+a[2]+a[3]+a[4]<max)
         return 5;
  return 0;
 }

它工作正常,但问题是它的复杂性。 任何人都可以提供任何建议来进一步优化此代码或提供更好的逻辑来实现它。

我对这类事情没有任何经验,所以很可能有更好的方法,但我确实有一些可能有用的见解。

目前您正在计算每种可能的组合,您应该能够改变算法以使其能够消除某些组合,而无需计算它们。

我会先对数组进行排序,这样可以在不计算数值的情况下消除某些值。

例如,如果你有一个看起来像[1,2,4,5,9]和min = 11和max = 14的数组,那么你的算法将检查1 + 2,1 + 4,1 + 5,1 + 9然后2 + 4,2 + 5,2 + 9,4 + 5,4 + 9才得到答案。

如果你首先从最高的数字开始,你可以通过计算9 + 1来消除所有可能的1个组合,因为9 + 1 <= 11必须是所有其他可能的1个组合对于两个数字总和无效的情况,与所有可能的2种组合相同。 如果你在代码中添加这样的逻辑,你应该有更少的多余计算,希望能加速你的代码。

这是一个功课问题吗?

你的问题真的不明确,但我会这样:

解决。 nlogn
首先添加第一个元素和最后一个元素。 那是在范围内吗? 从一端拿出第一个指针,从开头开始,将其移动到中间并添加中间数字和最后一个数字,第一个指针+最后一个指针。 是在范围内? 你可以将第一个指针移动到第一个和最后一个指针之间的中间位置,即:右边是序列的3/4。

所以你在这里使用二进制搜索,在排序的序列上有两个指针。

这将为您提供估计的元素数量,这些元素将在范围内。 我希望你有这个主意。

如果总和超出范围,则可以将第二个指针移动到中间。

这将给你nlogn

请注意,这仅适用于两个数字,我不确定您是否要求所有可能的数字添加在范围内或只有两个数字?

两个数字很容易, nlogn做到了

所有可能的子集都是np难的子集和问题。 指数,即2 ** n

我建议以下解决方案:

假设范围的最小值是minVal,最大值是maxVal。 现在对数组进行排序。让我们说数组的长度是len对数组中的数字进行二进制搜索只是<= maxVal。

搜索传递:我的意思是如果数字在索引i处,那么索引i + 1处的数字应该> = maxVal。 让我们说这个数字的索引是currIndex。 如果此数字等于maxVal,则在0到currIndex之间进行二进制搜索以获取数字

minVal和

搜索失败:这意味着最大数字是数组小于maxVal。 因此,对于这种情况,请按照以下步骤操作:1)将数组中的最大数字添加到结果集中。 2)现在从len-1 t0开始循环1.如果arr [len-1] + arr [len]小于maxVal,则将arr [len-1]添加到结果集并继续循环。 如果arr [len-1] + arr [len]> maxVal,则跳过并检查arr [len-1] + arr [len]。

等等。

这是一个相当复杂的问题,可能很难。

我想到的一件事是,它有点类似于“背包问题”。 也许你可以找到它的实现并进行调整。


如果预计最小数量的项目很小,您当然可以使用蛮力方法:

  1. 设置minVal = 1
  2. 找到所有尺寸minVal的集合
  3. 只要没有一组符合您的标准,请将1添加到minVal并转到步骤2

我认为你应该考虑对数组进行排序,有很多有效的算法。

然后从最大值开始并按排序顺序累加较小值,检查每一步的条件。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM