【问题标题】:Return the max sliding window返回最大滑动窗口
【发布时间】:2022-11-17 00:03:26
【问题描述】:

给定一个整数数组 nums 和一个大小为 k 的滑动窗口,它从数组的最左边移动到最右边。您只能在窗口中看到 k 个数字。每次滑动窗口向右移动一个位置。您必须计算窗口内的最大值。

Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
class Solution {
public:
    vector<int> maxSlidingWindow(vector<int> &nums, int k) {
        int n=nums.size();
        vector<int> answer;
        for(int i=0; i<n; i++){
            int mx = INT_MIN;
            for(int j=1; j<i+k; j++){
                mx = max(mx, nums[j]);
            }
            answer.push_back(mx);
        }
        while(answer.size()>n-k+1){
            answer.pop_back();
        }
        return answer;
        
    }
};

但是抛出错误

=================================================================
==31==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000090 at pc 0x000000345e1e bp 0x7ffef610bff0 sp 0x7ffef610bfe8
READ of size 4 at 0x603000000090 thread T0
    #2 0x7fb1bb36d0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
0x603000000090 is located 0 bytes to the right of 32-byte region [0x603000000070,0x603000000090)
allocated by thread T0 here:
    #6 0x7fb1bb36d0b2  (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Shadow bytes around the buggy address:
  0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff8000: fa fa 00 00 00 07 fa fa fd fd fd fa fa fa 00 00
=>0x0c067fff8010: 00 00[fa]fa 00 00 00 00 fa fa fa fa fa fa fa fa
  0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==31==ABORTING

【问题讨论】:

  • for(int j=1; j&lt;i+k; j++){ mx = max(mx, nums[j]); } 看起来它可以轻松越过 nums 数组的边界。为什么条件是j &lt; i+ k?记住 nums 有 n 元素可以小于 i+k
  • 让我尝试这样做
  • 也许j &lt; std::min(i+k,n)而不是j &lt; i+ k

标签: c++ dsa


【解决方案1】:
    for(int i=0; i<n; i++){
        int mx = INT_MIN;
        for(int j=1; j<i+k; j++){
            mx = max(mx, nums[j]);

假设k是3,n是2。当i=1时,j将转到3。nums[3]则出界。 j=1j&lt;i+k需要仔细审核。两者都错了。

另外,int mx = nums[i]; 更优雅,不涉及像 INT_MIN 这样的特殊常量。

【讨论】:

  • 那你有什么建议?
  • 我不是在为你做作业 :-)。拿纸和笔,选择一个 nk 并检查什么是有意义的。
  • 我只是在寻求提示,无论如何我记得有一些东西押韵为 DEQUE
【解决方案2】:

使用双端队列就可以了

vector<int> maxSlidingWindow(vector<int> &nums, int k) {
    int n = nums.size();
    deque<int> dq(k);
    vector<int> answer;
    for (int i = 0; i < k; i++) {
        while (dq.size() && nums[i] >= nums[dq.back()]) {
            dq.pop_back(); 
        }
        dq.push_back(i);
    }
    for (int i = k; i < n; i++){
        answer.push_back(nums[dq.front()]);
        while(dq.size() && dq.front() <= i - k) {
            dq.pop_front();
        } 
        while(dq.size() && nums[i] >= nums[dq.back()]) {
            dq.pop_back();
        }
        dq.push_back(i);
    }
    answer.push_back(nums[dq.front()]);
    return answer;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-12
    • 2012-05-30
    • 2017-04-03
    • 2022-09-27
    • 2011-05-06
    • 2021-10-12
    • 2015-02-28
    • 2017-09-03
    相关资源
    最近更新 更多