给定一个整数数组和一个数 k,计算每个长度为 k 的子数组的最大值
Posted
技术标签:
【中文标题】给定一个整数数组和一个数 k,计算每个长度为 k 的子数组的最大值【英文标题】:Given an array of integers and a number k, compute the maximum values of each subarray of length k 【发布时间】:2018-12-29 20:24:10 【问题描述】:问题: 给定一个整数数组和一个数字 k,其中 1
在 O(n) 时间和 O(k) 空间内执行此操作。您可以就地修改输入数组,并且不需要存储结果。您可以在计算它们时简单地打印出来。
示例: 给定数组 = [10, 5, 2, 7, 8, 7] 和 k = 3,我们应该得到:[10, 7, 8, 8],因为:
10 = 最大值(10, 5, 2)
7 = 最大值(5, 2, 7)
8 = 最大值(2, 7, 8)
8 = 最大值(7, 8, 7)
想法:
我想使用 std::max_element() 函数来解决这个问题,我注意到了一个模式。使用上面的例子
std::max_element(0, 2) = 10,其中 0 是迭代器的起始位置,2 是迭代器的结束位置。
std::max_element(1,3) = 7
std::max_element(2, 4) = 8
std::max_element(3,5) = 8
因此,对于任何 k,第一个迭代器总是从 0 到 n-2,其中 n 是向量或数组的大小,而 max_element 的右迭代器总是从 k-1 到 n-1。
虽然为各种 k 值指定正确的迭代器并不是很直接。正如您从我的代码中看到的那样,我坚持那部分,但我相信我的想法是合理的。我希望我说明了这个想法,以便其他人理解。
代码:
#include <iostream>
#include <vector>
#include <random>
#include <ctime>
// Given an array of integers and a number k, where 1 <= k <= length of the array, compute the maximum values
// of each subarray of length k.
// For example, given array = [10, 5, 2, 7, 8, 7] and k = 3, we should get : [10, 7, 8, 8], since :
// 10 = max(10, 5, 2)
// 7 = max(5, 2, 7)
// 8 = max(2, 7, 8)
// 8 = max(7, 8, 7)
// Do this in O(n) time and O(k) space. You can modify the input array in-place and you do not need to
// store the results. You can simply print them out as you compute them.
void printKMax(std::vector<int>& nums, int k)
int n = nums.size();
int i = 0;
int j = k - 1;
std::vector<int>::iterator it;
while (j <= n - 1)
it = std::max_element(nums.begin() + i, );
i++;
j++;
std::cout << *it << " ";
int main()
std::vector<int> nums = 10, 5, 2, 7, 8, 7;
int k = 3;
printKMax(nums, k);
std::cin.get();
问题:我在为 std::max_element 的右侧部分找到适用于各种 k 值的公式时遇到问题。任何帮助将不胜感激。
【问题讨论】:
以下链接提供了使用std::deque
的O(n)时间和O(k)空间算法:geeksforgeeks.org/…,请参见方法3。您的方法似乎是O(n*k)时间因为std::max_element
是 O(k)
【参考方案1】:
您将变量i
和j
保留为检查范围的开始和结束,因此您需要将std::max_element
专门应用于该范围。您正在寻找替换:
it = std::max_element(nums.begin() + i, );
与:
it = std::max_element(nums.begin() + i, nums.begin() + j + 1);
注意+ 1
部分。这是因为 STL 的标准约定是在右手边独占的范围内操作。
【讨论】:
这不是 O(k*n) 吗? @zahir 是的,但是 OP 没有要求算法。他也没有要求进行代码审查。他的问题具体而有针对性std::max_element
,所以我提供了答案。
@Snorrlaxxx 有可能,因为max_element
返回迭代器。
@bartop 这对解决 O(n) 有什么帮助?
@bartop 这根本无济于事。您仍然会每次比较 k
元素。好的算法会跟踪当前最大元素的索引,而不是为每组 k
元素使用 max_element
以上是关于给定一个整数数组和一个数 k,计算每个长度为 k 的子数组的最大值的主要内容,如果未能解决你的问题,请参考以下文章
2021-07-16:三个无重叠子数组的最大和。给定数组 nums 由正整数组成,找到三个互不重叠的子数组的最大和。每个子数组的长度为k,我们要使这3*k个项的和最大化。返回每个区间起始索引的列表(索