Sliding Window Maximum
滑动窗口最大值
题目描述
给定一个数组nums
,有一个大小为k
的滑动窗口,从数组的最左侧移动到数组的最右侧,滑动窗口每次只移动一位,返回滑动窗口中的最大值。
示例:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解法
解法一:暴力求解
时间复杂度:
O(kN)
空间复杂度:
O(n-k+1)
func maxSlidingWindow(nums []int, k int) []int {
var result []int
for i := 0; i <= len(nums)-k; i++ {
max := math.MinInt64
for j := 0; j < k; j++ {
if nums[i+j] > max {
max = nums[i+j]
}
}
result = append(result, max)
}
return result
}
解法二:使用队列求解
构造单调队列,队列中的元素单调递减
时间复杂度:
O(n)
空间复杂度:
O(n)
func maxSlidingWindow(nums []int, k int) []int {
result := []int{}
queue := []int{}
for i := 0; i < len(nums); i++ {
// 处理窗口中的元素
for len(queue) > 0 && queue[len(queue)-1] < nums[i] {
queue = queue[:len(queue)-1]
}
queue = append(queue, nums[i])
if i >= k-1 {
// 获取当前窗口的最大值
result = append(result, queue[0])
// 删除第一个元素
if len(queue) > 0 && queue[0] == nums[i-k+1] {
queue = queue[1:]
}
}
}
return result
}
解法三:双数组解法
这个解法很巧妙,但是解释起来也需要花上几句话,人懒直接上代码吧,代码好理解。
时间复杂度:
O(n)
空间复杂度:
O(n)
func maxSlidingWindow(nums []int, k int) []int {
result := []int{}
if len(nums) <= 0 {
return result
}
left := make([]int, len(nums))
right := make([]int, len(nums))
left[0] = nums[0]
right[len(right)-1] = nums[len(nums)-1]
for i := 1; i < len(nums); i++ {
if i%k == 0 {
left[i] = nums[i]
} else {
left[i] = max(left[i-1], nums[i])
}
j := len(nums) - i - 1
if (j+1)%k == 0 {
right[j] = nums[j]
} else {
right[j] = max(right[j+1], nums[j])
}
}
for i := 0; i <= len(nums)-k; i++ {
result = append(result, max(right[i], left[i+k-1]))
}
return result
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
Last updated
Was this helpful?