给定一个整数数组和一个数 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】:

您将变量ij 保留为检查范围的开始和结束,因此您需要将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个项的和最大化。返回每个区间起始索引的列表(索

二分模版题

数的范围(整数二分)

数的范围

和为k的子数组

编程题#3:整数的个数