给定一个大小为N的数组,我需要找到在最小和最大范围内总和的最小值数。
例如:考虑一个数组[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;
}
它工作正常,但问题在于它的复杂性。任何人都可以提供任何进一步优化此代码的建议,或提供更好的逻辑来实现这一点。
答案 0 :(得分:1)
我对这类事情没有任何经验,所以很可能有更好的方法,但我确实有一些可能有帮助的见解。
目前您正在计算每种可能的组合,您应该能够改变算法以使其能够消除某些组合,而无需计算它们。
我会先对数组进行排序,这样可以在不计算值的情况下消除某些值。
例如,如果你有一个看起来像[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种组合相同。如果你在代码中添加这样的逻辑,你应该有更少的多余计算,希望能加速你的代码。
答案 1 :(得分:1)
这是一个功课问题吗?
你的问题真的不明确,但我会这样做:
排序。的 nlogn 即可。
首先添加第一个元素和最后一个元素。那是在范围内吗?
从一端拿出第一个指针,从开头开始,将其移动到中间并添加中间数字和最后一个数字,第一个指针+最后一个指针。
是在范围内?你可以将第一个指针移动到第一个和最后一个指针之间的中间位置,即:右边是序列的3/4。
所以你在这里使用二分搜索,在分类序列上有两个指针。
这将为您提供估计的元素数量,这些元素将在范围内。我希望你有这个想法。
如果总和超出范围,您可以将第二个指针移动到中间位置。
这将为您提供 nlogn 。
请注意,这仅适用于两个数字,我不确定您是否要求所有可能的数字添加到范围内或只有两个数字?
两个数字很容易, nlogn 可以吗
所有可能的子集都是子集和问题, np hard 。指数, 2 ** n 。
答案 2 :(得分:1)
我建议采用以下解决方案:
假设范围的最小值是minVal,最大值是maxVal。 现在对数组进行排序。让我们说数组的长度是len 对数组中的数字进行二进制搜索,该数字只是&lt; = 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]&gt;然后maxVal跳过并检查arr [len-1] + arr [len]。
等等。
答案 3 :(得分:0)
我认为你应该考虑对数组进行排序,这有很多有效的算法。
然后从最大值开始,累计按排序顺序添加较小的值,检查每一步的条件。
答案 4 :(得分:0)
这是一个相当复杂的问题,可能很难。
有一件事让我想到它有点像'背包问题'。也许你可以找到它的实现并进行调整。
如果项目的最小数量预计很小,您当然可以使用蛮力方法: