我们获得了一个包含n
值的数组。
示例:[1,4,5,6,6]
对于数组i
的每个索引a
,我们构造一个数组b
的新元素,
b[i]= [a[i]/1] + [a[i+1]/2] + [a[i+2]/3] + ⋯ + [a[n]/(n−i+1)]
,其中[.]
表示最大的整数函数。
我们也给了整数k
。
我们必须找到最小值i
,以使b[i] ≤ k
。
我知道蛮力O(n^2)
算法(用于创建数组-'b'),有人可以建议更好的时间复杂度和解决方法吗?
例如,对于输入[1,2,3]
,k=3
,输出为1(minimum-index)
。
a[1]=1; a[2]=2; a[3]=3;
现在,b[1] = [a[1]/1] + [a[2]/2] + [a[3]/3] = [1/1] + [2/2] + [3/3] = 3;
b[2] = [a[2]/1] + [a[3]/2] = [2/1] + [3/2] = 3;
b[3] = [a[3]/1] = [3/1] = 3 (obvious)
现在,我们必须找到索引i
,以使b[i]<=k
,k='3'
以及b[1]<=3
,因此1
是我们的答案! :-)
约束:-时间限制:-( 2秒),1 <= a [i] <= 10 ^ 5,1 <= n <= 10 ^ 5,1 <= k <= 10 ^ 9
答案 0 :(得分:4)
这是一种c_sub_category
时间算法,用于计算c_sub_categories
数组,其中$data = Tickets
::whereBetween('created_at', [$week["startDate"], $week["endDate"]])
->where('status', 'closed')
->where('category', '!=', 'New Development')
->groupBy('c_sub_category')
->get();
是whereBetween
数组中的元素数,而$data = Tickets
->where('status', 'closed')
->where('category', '!=', 'New Development')
->groupBy('c_sub_category')
->get();
是最大值$data = Tickets
::where(function ($query) use ($week) {
$query->whereBetween('created_at', [$week["startDate"], $week["endDate"]]);
})
->where('category', '!=', 'New Development')
->where('status', 'closed')
->groupBy('c_sub_category')
->get();
$data = Tickets
::where(function ($query) use ($week) {
$query->whereBetween('created_at', [$week["startDate"], $week["endDate"]]);
})
->where(function ($query) use ($week) {
$query->where('category', '!=', 'New Development');
->where('status', 'closed');
})
->groupBy('c_sub_category')
->get();
数组的元素。
此算法计算O(n √A)
数组(b
)的差分序列,并得出n
本身作为累积和。由于差异是线性的,因此我们可以从a
开始,在每个元素A
上循环,然后在适当的位置添加a
的差异序列。关键在于该差异序列是稀疏的(少于b
个元素)。例如,对于∆b = b[0], b[1] - b[0], b[2] - b[1], ..., b[n-1] - b[n-2]
,
b
我们可以从子例程中得出差值序列,该子例程在给定正整数∆b = 0, 0, ..., 0
的情况下,返回所有最大对的正整数a[i]
,使得对数[a[i]], [a[i]/2], [a[i]/3], ...
。
请参阅下面的完整Python代码。
2√a[i]
答案 1 :(得分:1)
这可能无法达到David Eisenstat的回答的效率,但是由于我花了很长时间弄清楚一个实现,所以我认为无论如何都要放弃它。实际上,它似乎是O(n^2)
。
b[i]
的元素可能不规则,但其中的某些部分不是:
[a[1]/1] + [a[2]/2] + [a[3]/3]
|------ s2_1 -----|
|-s1_1-|
[a[2]/1] + [a[3]/2]
|------ s2_2 -----|
|-s1_2-|
[a[3]/1]
|-s1_3-|
s2_1 < s2_2
s1_1 < s1_2 < s1_3
在k
上二元搜索s1
。 s1_i
大于k
的任何结果都将排除一部分有序行(行为b_i
s)。
在其余行的k
上二元搜索s2
。 s2_i
大于k
的任何结果都将排除一部分有序行(行为b_i
s)。
这没有太大帮助,因为在最坏的情况下,我们的O(n ^ 2 * log n)复杂度大于O(n ^ 2)。
但是我们也可以水平搜索。如果我们知道b_i ≤ k
,那么它将排除所有长度更大或相等的 行,并且排除了搜索较小的s(m)
的需要,而不是因为较小的{{1} } s不能产生> = k的总和,但是因为它们必然会产生一个具有较高s(m)
的和,因此我们正在寻找最小值i
。
JavaScript代码:
i
答案 2 :(得分:-1)
为什么计算b[i]
会导致O(n²)?如果为i = 1
,则需要执行n
的步骤。如果为i = n
,则需要一步来计算b [i] ...
在Sum > k
条件下中止总和时,可以改善计算。
Let a in N^n
Let k in N
for (i1 := 1; i1 <= n; i1++)
b := 0
for (i2 :=i1; i2 <= n; i2++) // This loop is the calculation of b[i]
b := b + ceil(a[i2]/(i2 + 1))
if (b > k)
break
if (i2 == n)
return i1