C++:查找子数组数组中的最大整数
C++: Find the maximum integer in an array of sub-arrays
我遇到了一个问题,我想编写一个算法,该算法可以返回较大数组中k个元素的每个连续子数组的最大元素,并将这些max元素读入自己的数组中,如下所示:
Given int array = {3, 7, 20, 6, 12, 2, 0, 99, 5, 16}, and int k = 4,
--> creates the array {20, 20, 20, 12, 99, 99, 99}
[because there are 7 consecutive sub-arrays of size 4 within the given array:
{3, 7, 20, 6}, {7, 20, 6, 12}, {20, 6, 12, 2}, ... , {0, 99, 5, 16}
and the max element of these, respectively, is 20, 20, 20, ..., 99 which
are read into the resulting array.
现在这是我的问题:我知道如何在 O(n^2( 复杂性中实现它,但想让它更快,以便它可以是 O(n(,或者如果不可能,则为 O(nlog(n((。有谁知道是否有更快的方法来做到这一点,如果有,如何?
首先,朴素算法的复杂性是 O(k(n-k+1(((通常这近似于 O(k.n((,而不是 O(n^2(。 这就是,对于每个连续的子数组(可能为 n-k+1(,您必须执行 k 比较。
你可以通过一些记忆做得更好,使用一个额外的长度 k 数组,我们可以称之为 maximums
. 该数组将存储下一个最大值的索引。
对于数据集的每次迭代,您检查maximums
的第一个元素。 您删除任何"过期"索引,现在第一个元素是当前迭代的答案。
当您在数据上滑动窗口(大小 k(时,将当前索引推到maximums
上,然后按如下方式修剪它:索引 maximums[i]
处的值必须小于索引 maximums[i-1]
处的值。 如果不是,那么您继续在maximums
的开头冒泡索引,一次一个点,直到这成为真的。
实际上,最好将maximums
数组视为环形缓冲区。 修剪过程会将尾巴缩小回头部,而弹出任何"过期"的最大值(当窗口滑过它们时(会将头部向前推进一步。
这有点笨拙,但这里有一些工作代码来说明:
#include <vector>
#include <iostream>
int main()
{
const int window_size = 4;
std::vector<int> vals = { 3, 7, 20, 6, 12, 2, 0, 99, 5, 16 };
std::vector<int> maximums( window_size );
int mhead = 0, mtail = 0;
for( int i = 1; i < vals.size(); i ++ )
{
// Clean out expired maximum.
if( maximums[mhead] + window_size <= i )
{
int next_mhead = (mhead + 1) % window_size;
if( mtail == mhead ) mtail = next_mhead;
mhead = next_mhead;
}
if( vals[i] >= vals[ maximums[mtail] ] )
{
// Replace and bubble up a new maximum value.
maximums[mtail] = i;
while( mhead != mtail && vals[ maximums[mtail] ] >= vals[ maximums[(mtail+window_size-1)%window_size] ] )
{
int prev_mtail = (mtail + window_size - 1) % window_size;
maximums[prev_mtail] = maximums[mtail];
mtail = prev_mtail;
}
}
else
{
// Add a new non-maximum.
mtail = (mtail + 1) % window_size;
maximums[mtail] = i;
}
// Output current maximum.
if( i >= window_size - 1 )
{
std::cout << vals[ maximums[mhead] ] << " ";
}
}
std::cout << std::endl;
return 0;
}
现在,时间复杂度...
最好的情况是 O(n(,如果所有数据都已排序(升序或降序(,就会发生这种情况。
我相信,最坏的情况是O(2n(。 在一次迭代中需要 k 个额外操作的唯一方法是,如果您已经有 k 个线性复杂度的步骤(以便环形缓冲区已满(。 在这种情况下,环形缓冲区将在下一步中为空。 由于我们只能填充和清空环形缓冲区 n/k 次,因此这些偶尔的 k 操作以 k.n/k 或仅 n 出现。
您应该能够证明,即使环形缓冲区的持续部分清空也会导致同样的复杂性。
最后,我们可以总结并称整个事情为O(n(,因为任何常数因子对于大n都变得微不足道。 它实际上比我预期的要好。=)
- C++使用整数的压缩数组初始化对象
- 在一定长度后从数组中打印时缺少整数
- 是否基于数组B整数打印数组A中的整数
- 检查TCHAR数组输入是否为带符号整数C++
- 如何将以逗号和空格分隔的整数读取到 2D 数组中?
- 从二进制文件中读取整数数组
- 整数区间(或 int 数组)中每个数字的出现次数
- 新的整数数组向右移动?
- C++ 中的二维整数数组,每行中的元素数量不均匀
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- 给定一个整数数组,需要在Max_Heap上运行操作。得到错误"segmentation fault",有什么想法吗?(C++)
- 为什么在我的 main 函数中声明整数后我的整数数组中会出现错误?
- 如何将字符串和整数读取到两个单独的动态数组中的程序编写?
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- C++数组输入不接受一定数量的整数
- 从两个 4x64 位整数数组中获取取模
- 如何计算数组整数的总可能组合
- 2D 字符串数组 C++:整数串联成字符串
- 将数组整数2除以偶数和
- 将2d数组整数数据从c++发送到qml