9.返回滑动窗口中的最大值

1. 239 滑动窗口最大值

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

 

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7] 
解释:

滑动窗口的位置 最大值
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

 

提示:

你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。

2.  解法1 使用双端队列

#解法1 使用双端队列
耗时:2408 ms, 内存消耗:31.3M
func maxSlidingWindow(nums []int, k int) []int {
    if nums == nil || len(nums) == 0 || k <= 0 {
        return nil
    }
    
    var window, res = make([]int,0), make([]int,0)
    
    for i, v := range nums{
        if i >=k && window[0] <= i-k{
            window = window[1:]
        }
        
        for len(window) > 0 && nums[window[len(window)-1]] <= v {
            window = window[:len(window)-1]
        }
        
        window = append(window, i)
        
        if i >= k-1 {
            res = append(res,nums[window[0]])
        }
    }
    return res
}

3. 解法2 双端队列升级版

#解法2 使用index减少切片操作
func maxSlidingWindow(nums []int, k int) []int {
   if nums == nil || len(nums) == 0 || k <= 0 {
        return nil
    }
    
    var window, res = make([]int,len(nums)), make([]int, len(nums)-k+1)
    head := 0
    tail := -1
    
    for i, v := range nums{
        if i >=k && window[head] <= i-k{
            head++
        }
        
        for head <= tail  && nums[window[tail]] <= v {
            tail--
        }
        
        tail++
        window[tail] = i
        fmt.Println(window)
        if i >= k-1 {
            res[i-k+1] = nums[window[head]]
        }
    }
   
    return res
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 滑动窗口最大值指的是一个固定长度的数字序列最大值。它通常用于数据流处理,并且可以使用一个队列来维护滑动窗口内的数字。 以下是一个用 Python 实现滑动窗口最大值的示例代码: ``` from collections import deque def max_in_sliding_window(nums, k): if not nums: return [] q = deque() res = [] for i in range(len(nums)): while q and nums[q[-1]] <= nums[i]: q.pop() q.append(i) if q[0] == i - k: q.popleft() if i >= k - 1: res.append(nums[q[0]]) return res ``` 其 `nums` 是输入数字序列,`k` 是滑动窗口的长度。该代码返回每个滑动窗口最大值组成的列表。 ### 回答2: 滑动窗口最大值是一种常用的算法思想,可以用于解决一些与连续子数组相关的问题。在Python,我们可以使用双端队列实现滑动窗口最大值查找。 具体实现过程如下: 1. 首先,我们需要创建一个双端队列(deque)来存储滑动窗口的元素索引。我们将队列的索引按照元素大小降序排列,以便可以快速找到最大值。 2. 然后,我们需要遍历整个数组,并在每次迭代执行以下步骤: a. 检查双端队列的头部元素(即索引)是否已经超出当前窗口的范围。如果超出了范围,我们需要将其从队列弹出。 b. 将当前元素添加到队列。在添加之前,我们需要将队列所有小于当前元素的索引都弹出,以保持队列的索引按照元素大小降序排列。 c. 检查当前索引与窗口的起始位置的差值是否大于等于窗口的大小K。如果是,说明当前窗口已经满了,我们可以将队列的头部元素作为当前窗口的最大值。 3. 最后,我们可以将所有窗口的最大值存储在一个数组,并返回数组作为最终结果。 以下是一个示例代码: ``` from collections import deque def maxSlidingWindow(nums, k): result = [] queue = deque() for i in range(len(nums)): # 检查队列的头部元素是否超出窗口范围 if queue and queue[0] <= i - k: queue.popleft() # 弹出所有小于当前元素的索引 while queue and nums[queue[-1]] < nums[i]: queue.pop() # 将当前元素添加到队列 queue.append(i) # 检查窗口是否已经满了 if i >= k - 1: result.append(nums[queue[0]]) return result # 测试 nums = [1,3,-1,-3,5,3,6,7] k = 3 print(maxSlidingWindow(nums, k)) ``` 以上代码的输出为:[3, 3, 5, 5, 6, 7]。 这样,我们就成功实现了滑动窗口最大值查找的功能。 ### 回答3: 滑动窗口最大值是指在一个给定数组,长度为k的窗口从左至右滑动,每次滑动窗口都需要找到窗口最大值。下面是一个用Python实现滑动窗口最大值的示例代码: ``` def find_max_in_window(arr, k): if not arr or k <= 0 or k > len(arr): return [] max_nums = [] deque = [] for i in range(len(arr)): # 检查队首元素是否还在窗口范围,如果不在则删除 if deque and deque[0] <= i - k: deque.pop(0) # 如果当前遍历元素大于队尾元素,删除队尾元素直到当前元素小于队尾元素或队列为空 while deque and arr[i] >= arr[deque[-1]]: deque.pop() deque.append(i) # 当前窗口已形成 if i >= k - 1: max_nums.append(arr[deque[0]]) return max_nums ``` 在这个代码,我们使用一个双端队列(deque)来保存当前窗口的元素索引。其deque的特点是队首元素是当前窗口最大值,队列较小的元素按照递减顺序排列。在遍历数组时,我们首先检查队首元素是否还在窗口范围内,如果不在窗口范围内,删除队首元素。然后,我们将当前元素与队列的元素进行比较,如果当前元素比队尾元素大,删除队尾元素,直到当前元素小于队尾元素或队列为空。最后,将当前元素的索引加入队列。 当遍历到第k个元素时,当前窗口已经形成,此时队首元素就是当前窗口最大值,将其添加到结果集。接着,继续遍历数组,每次遍历窗口滑动一次,重复上述步骤找到最大值,直到遍历完整个数组。 调用该函数,可以输出滑动窗口最大值。如下所示: ``` arr = [1, 3, -1, -3, 5, 3, 6, 7] k = 3 max_nums = find_max_in_window(arr, k) print(max_nums) ``` 输出结果为:[3, 3, 5, 5, 6, 7],表示滑动窗口最大值为3, 3, 5, 5, 6, 7。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值