大小为L的子数组中的最小数字。我必须为数组的所有子数组找到它。除了单独扫描所有子阵列之外还有其他方法吗?
我有一个解决方案:
a[n]//the array
minimum[n-l+1]//the array to store the minimum numbers
minpos=position_minimum_in_subarray(a,0,l-1);
minimum[0]=a[minpos];
for(i=1;i<=n-l-1;i++)
{
if(minpos=i-1)
{
minpos=position_minimum_in_subarray(a,i,i+l-1);
}
else {
if(a[minpos]>a[i+l-1]) minpos=i+l-1;
minimum=a[minpos];
}
}
有没有比这更好的解决方案?
答案 0 :(得分:2)
你可以使用双端队列(Q)。找到一种方法,使得最小元素总是出现在Q的前面,Q的大小永远不会超过L.因此,你总是最多插入和删除一次元素制定解决方案O(n)。我觉得这足以让你前进。
答案 1 :(得分:1)
我认为您的解决方案没问题,但要正常工作,应该是这样的:
a[n]//the array
minimum[n-l+1]//fixed
minpos=position_minimum_in_subarray(a,0,l-1);
minimum[0]=a[minpos];
for(i=1;i<=n-l-1;i++)
{
if(minpos=i-1)
minpos=position_minimum_in_subarray(a,i,i+l-1);
else if(a[minpos]>a[i+l-1]) //fixed
minpos=i+l-1; //fixed
minimum[i] = a[minpos];
}
// Complexity Analysis :
//Time - O(n^2) in worse case(array is sorted) we will run
"position_minimum_in_subarray" on each iteration
//Space - O(1) - "minimum array" is required for store the result
如果您想提高时间复杂度,可以使用额外的空间。 例如,您可以将每个子数组存储在一些自平衡BST(例如红黑树)中,并在每次迭代时获取最小值:
for (int i= 0; i<n; i++) {
bst.add(a[i]);
if (bst.length == l) {
minimum[i-l] = bst.min;
bst.remove(a[i - l]);
}
}
//It's still not O(n) but close.
//Complexity Analysis :
//Time - O(n*log(l)) = O(n*log(n)) - insert/remove in self-balancing tree
is proportional to the height of tree (log)
//Space - O(l) = O(n)
答案 2 :(得分:0)
Scala版本答案
def movingMin(windowSize: Int, array: Seq[Double]) = {
(1 to array.length - (windowSize - 1)).
map{i => (array.take(i + (windowSize - 1)).takeRight(windowSize)).min}
}