首页 > 其他分享 >滑动窗口最大值

滑动窗口最大值

时间:2024-06-03 10:11:35浏览次数:14  
标签:窗口 temp nums int 最大值 队列 滑动

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

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

示例 1:

输入: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
示例 2:

输入:nums = [1], k = 1
输出:[1]

提示:

1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length

< 此题难度非常高 我自己的实现没有通过测试 卡在了时间复杂度上 后来根据题解修改才通过
< 有两种思路 单调队列和预处理 预处理更是非常巧妙

  • 单调队列
package main

func main() {

	// temp := trap([]int{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1})
	temp := maxSlidingWindow([]int{1, 3, -1, -3, 5, 3, 6, 7}, 3)
	// println(temp)
	for _, v := range temp {
		println(v)
	}
	// for i := 0; i < len(temp); i++ {
	// 	for j := 0; j < len(temp[i]); j++ {
	// 		print(temp[i][j], " ")
	// 	}
	// 	println()
	// }
}

// maxSlidingWindow 计算滑动窗口中的最大值
// nums: 给定的整数数组
// k: 滑动窗口的大小
// 返回值: 一个整数数组,包含每个滑动窗口中的最大值
func maxSlidingWindow(nums []int, k int) []int {
	// q: 使用切片来模拟一个单调递减队列(实际上是一个索引队列)
	// 它保存的是数组nums中元素的索引,且索引对应的元素值在队列中是单调递减的
	q := []int{}

	// push: 一个内部函数,用于向队列中添加元素
	push := func(i int) {
		// 当队列不为空,且当前元素的值大于或等于队列尾部元素的值时
		// 移除队列尾部的元素,因为当前元素的值更大,可能成为新的窗口最大值
		for len(q) > 0 && nums[i] >= nums[q[len(q)-1]] {
			q = q[:len(q)-1]
		}
		// 将当前元素的索引添加到队列尾部
		q = append(q, i)
	}

	// 初始化窗口,将前k个元素的索引添加到队列中
	for i := 0; i < k; i++ {
		push(i)
	}

	// n: 数组nums的长度
	n := len(nums)

	// ans: 用于保存每个滑动窗口中的最大值的切片
	// 初始容量为1,但预计最终容量为n-k+1(因为总共有n-k+1个滑动窗口)
	ans := make([]int, 1, n-k+1)

	// 队列头部的索引对应的元素就是当前窗口的最大值
	// 将第一个窗口的最大值添加到结果切片中
	ans[0] = nums[q[0]]

	// 从第k个元素开始遍历到数组末尾
	// 因为前k个元素已经初始化过窗口和结果切片
	for i := k; i < n; i++ {
		// 将新元素的索引添加到队列中
		push(i)

		// 如果队列头部的索引已经超出当前窗口的范围(即小于i-k+1),则移除它
		// 因为这个索引对应的元素不再是当前窗口的一部分
		for q[0] <= i-k {
			q = q[1:]
		}

		// 队列头部的索引对应的元素就是当前窗口的最大值
		// 将它添加到结果切片中
		ans = append(ans, nums[q[0]])
	}

	// 返回结果切片
	return ans
}

  • 预处理
package main

func main() {

	// temp := trap([]int{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1})
	temp := maxSlidingWindow([]int{1, 3, -1, -3, 5, 3, 6, 7}, 3)
	// println(temp)
	for _, v := range temp {
		println(v)
	}
	// for i := 0; i < len(temp); i++ {
	// 	for j := 0; j < len(temp[i]); j++ {
	// 		print(temp[i][j], " ")
	// 	}
	// 	println()
	// }
}

// maxSlidingWindow 函数接收一个整数数组 nums 和一个整数 k,返回滑动窗口大小为 k 的所有子数组中的最大值组成的数组
func maxSlidingWindow(nums []int, k int) []int {
	n := len(nums)
	prefixMax := make([]int, n) // 用于存储每个窗口的前缀最大值
	suffixMax := make([]int, n) // 用于存储每个窗口的后缀最大值

	// 计算前缀最大值
	for i, v := range nums {
		if i%k == 0 {
			prefixMax[i] = v
		} else {
			prefixMax[i] = max(prefixMax[i-1], v)
		}
	}

	// 计算后缀最大值
	for i := n - 1; i >= 0; i-- {
		if i == n-1 || (i+1)%k == 0 {
			suffixMax[i] = nums[i]
		} else {
			suffixMax[i] = max(suffixMax[i+1], nums[i])
		}
	}

	ans := make([]int, n-k+1) // 存储最终结果
	for i := range ans {
		ans[i] = max(suffixMax[i], prefixMax[i+k-1])
	}
	return ans
}

// max 函数用于返回两个整数中的较大值
func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

标签:窗口,temp,nums,int,最大值,队列,滑动
From: https://www.cnblogs.com/sunchenxuan/p/18228196

相关文章

  • Android启动窗口SplashScreen
    Android启动窗口SplashScreen首先介绍下什么是启动窗口,对于大部分应用冷启动时的场景都会有启动窗口,为了让效果更明显,在如下代码中(只是一个基本的可以运行的应用即可)添加了sleep5s的代码,在按recent键移除应用后,再点击桌面图标,即可看到启动窗口效果,即使点击后界面内容显示出来前的......
  • dotnet C# 创建 X11 应用时设置窗口背景颜色
    本文将告诉大家如何在X11里面创建一个窗口时,设置窗口的背景颜色在dotnetC#设置X11应用窗口背景透明的基础上,可以通过创建XColor结构体,将XColor赋值给到XSetWindowAttributes的background_pixel进行设置窗口的初始化背景颜色核心实现如下先创建XColor结构体,代......
  • 统计子矩阵+二维前缀和+滑动窗口
    题目链接:0统计子矩阵-蓝桥云课(lanqiao.cn)代码#include<iostream>usingnamespacestd;constintN=505;intnum[N][N];intmain(){ intn,m,k; cin>>n>>m>>k; intcount=0; for(inti=1;i<=n;i++){ for(intj=1;j......
  • telnet HTTP测试步骤、遇到的问题和解决方法(cmd窗口)
    **本篇文章食用的简单说明**本篇文章为使用cmd窗口进行telnetHTTP测试步骤以及遇到的问题和解决方法。其中在解决方法中有文字版和图片版,文字版图片版自己选择一种查看就好(有标注)。目录点击想要查看的部分即可跳转到对应位置。目录**本篇文章食用的简单说明**---------......
  • HTML一键打包工具1.9.96更新发布, 新增自动保存窗口状态, 优化一机一码功能 (附下载地
    HTML一键打包EXE工具是一款强大的HTML转EXE程序,能够将任意HTML项目或网页转换为独立的EXE文件。您无需额外安装浏览器或服务器,用户只需简单双击即可运行项目。无论您是在制作KRPano全景VR项目,开发WebGL游戏(如Egret、Cocos、RPGMVMaker),还是需要打包课件或网站,这款工具都能帮助您......
  • SQL KEEP 窗口函数等价改写案例
    一哥们出条sql题给我玩,将下面sql改成不使用keep分析函数的写法。selectdeptno,ename,sal,hiredate,min(sal)keep(dense_rankfirstorderbyhiredate)over(partitionbydeptno)min_sal,max(sal)keep(dense_ranklastorderby......
  • Leecode热题100--215:数组中的第k个最大值
    题目:给定整数数组nums和整数k,请返回数组中第k个最大的元素。请注意,你需要找的是数组排序后的第k个最大的元素,而不是第k个不同的元素。时间复杂度为O(n)的算法解法一:利用STL特性解题:#include<iostream>#include<vector>#include<algorithm>usingnamespac......
  • 如何隐藏 Firefox 窗口(Selenium WebDriver)?
    在Python中使用SeleniumWebDriver隐藏Firefox窗口通常涉及到配置FirefoxOptions来禁用其图形界面的显示。以下是一个详细的步骤和代码示例:1.首先,确保你已经安装了selenium库,以及geckodriver(适用于Firefox浏览器)。如果还没有安装,可以通过pip进行安装:```bashpipinstallsel......
  • 基于Matlab高斯滑动窗口滤波器
    欢迎大家点赞、收藏、关注、评论啦,由于篇幅有限,只展示了部分核心代码。文章目录一项目简介二、功能三、系统四.总结一项目简介  一、项目背景与意义在数字图像处理中,图像滤波是一项基本且重要的技术,用于去除图像中的噪声、增强图像的某些特征或改善图像的......
  • Debug-012-el-popover 使用 doClose() 关闭窗口不生效的处理方案
     前言:    今天上午碰见一个非常奇怪的情况:一样的方法实现的功能,效果却不一样。两个页面都是使用的doClose()去关闭的el-popover,其中有一个就是不生效,找不同找了半天,始终不得其解。请看效果吧:el-popover-doClose()-ok视频1(el-popover-doClose()-关闭成功的)e......