以这样的方式填充数组,使每个元素等于两个数字的最小和
Filling an array in such a way that each element equal to minimum sum of two numbers such that
给定一个数组(只包含正整数),并且已经有k个元素:a1, a2, ....<> k 。
我需要填充剩余的(n - k)元素(数组总共有n元素)。
n的值是 10 ^ 3 和 1 & lt; = & lt; k = n 。
每个ai的值是两个数的最小和,使得这两个数的位置之和等于i。
下面是伪代码(我的算法):
for i = k + 1 to n
a[i] = max_value
for j = 1 to (i / 2)
a[i] = min(a[i], a[j] + a[i - j])
时间复杂度:O(n ^ 2)问题是:有没有其他更快的方法?
我正在寻找任何数据结构或算法,可以找到每个a I 小于O(n)的值。
P/S:这是我的程序中的一个过程,所以我需要尽快完成。
您可以通过使用线程并行运行您的最小值检查来提高程序速度。例如,您可以运行4个线程,每个线程检查j范围的1/4。这将略微提高速度,但您的算法仍然需要O(n^2)的运行时间。
我同意你很可能不能超过O(n^2)的评论。所以你最好的选择可能是尝试这样的事情来优化你的代码,以减少n^2前面的系数。
创意1
AFAICT这不能保证在O(n^2)上得到改进,但它应该在实践中使内循环周期的数量减少很多。基本的想法是,我们可以在内部循环中以不同的顺序测试对,这使我们能够在很多时候提前完成。具体来说,我们首先对数字的位置进行排序,并将其存储在s[]
中,因此a[s[i]]
是a[]
中第i小的数字。然后在主内循环中,我们用a[s[j]]
代替a[j]
(a[i - s[j]]
代替a[i - j]
)按第一项递增的顺序形成成对和。这给了我们两种方法来提前停止内循环:
- 如果
a[s[j]] >= a[i]
,那么我们可以停止,因为每个后面的和必须更大,因为它们每个(a[s[j+1]]
等)的第一项必须至少与迄今为止的最佳解(已经在a[i]
中)一样大,而另一项永远不能是负的。 - 如果
a[i - s[j]] <= a[s[j]]
(也就是说,如果下一个最小数的"伙伴"小于或等于它),我们可以停止,原因更复杂。相反,假设后来有一些更好的配对和a[s[m]] + a[i - s[m]]
(即m > j
)。我们知道第一项a[s[m]]
,必须至少和现在的第一项a[s[j]]
一样大因为我们是按递增顺序访问第一项,m > j
;因此,为了使配对和a[s[m]] + a[i - s[m]]
优于(即小于)a[s[j]] + a[i - s[j]]
,它的第二项a[i - s[m]]
必须小于当前的第二项a[i - s[j]]
。(这不是充分条件,但在这里无关紧要。)但是由于我们刚刚观察到a[i - s[j]] <= a[s[j]]
,我们也知道a[i - s[m]] < a[s[j]]
,这意味着a[i - s[m]]
必须出现在作为我们之前已经处理过的对和中的第一项 !这与m > j
相矛盾,意味着不存在更好的配对和,所以我们可以安全地停止。
我期望第二个条件能够移除很多内循环;第一种方法可能只对有少量小数和大量非常高的数字的数据集有很大帮助,并且可以用小数的对和来覆盖大多数位置。
额外的效率:如果我们实现上面的第二个条件,那么我们实际上不需要单独的j < i / 2
循环终止测试,因为在检查任何i / 2 + 1
对和之后,我们必须至少遇到两次对和(一次交换了第一项和第二项),这将导致条件2触发并退出循环。
伪代码:
s[1 .. k] = 1 .. k
sort s using comparator function comp(i, j) { a[i] < a[j] }
for i = k + 1 to n
a[i] = max_value
for (j = 1; a[s[j]] < a[i] && a[i - s[j]] > a[s[j]]; ++j)
a[i] = min(a[i], a[s[j]] + a[i - s[j]])
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 高级选择排序 - 在一次迭代中搜索两个元素
- 如何仅考虑 *指针中的前两个元素
- 为什么具有两个元素的发起器语法将一个元素而不是两个元素放入字符串向量中?
- 如何共享特定于两个类的逻辑?
- 是否可以交换在 c++ 中作为函数 func(say) 中的参数传递的 const 向量的两个元素,例如:vector<int>func (const vector<int>&
- C++ std::向量插入两个元素替代算法失败
- 为什么我的类只适用于两个构造函数 C++
- 数组中两个元素的最大异或
- 我无法将二维数组的两个元素的差异分配给C++中其他数组的元素?
- 如何将比较运算符应用于两个匿名结构中的每个变量
- 一个数组可以划分的最大子数组,使得不同子数组中任意两个元素的 GCD 始终为 1?
- 找到两个相关索引,其中两个元素等于目标值
- 在不使用递归的情况下将 FFT 应用于两个非常大的数字的乘法
- C++ - 前两个元素之间的差异
- C :交换两个不同向量的两个元素
- C 查找两个元素中出现的次数的数量
- 如何连接向量的两个元素
- 使用STL仅对两个元素进行排序
- 使用STL交换静态数组中的两个元素