欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言滑動(dòng)窗口最大值的實(shí)現(xiàn)示例

 更新時(shí)間:2025年08月14日 11:07:23   作者:程序員愛釣魚  
本文主要介紹了Go語言滑動(dòng)窗口最大值的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在高性能計(jì)算、數(shù)據(jù)分析、監(jiān)控系統(tǒng)等應(yīng)用中,實(shí)時(shí)處理數(shù)據(jù)流是一項(xiàng)基礎(chǔ)能力。其中一個(gè)典型的需求是:在一個(gè)不斷移動(dòng)的區(qū)間(窗口)內(nèi),快速求出當(dāng)前區(qū)間的最大值。這就是我們今天要實(shí)現(xiàn)的算法——滑動(dòng)窗口最大值(Sliding Window Maximum) 。

一、問題描述與示例

給定一個(gè)整數(shù)數(shù)組 nums 和一個(gè)整數(shù) k(窗口大?。覀冃枰敵鲆粋€(gè)數(shù)組,表示從左到右依次滑動(dòng)窗口后,每個(gè)窗口中的最大值。

示例

輸入:
nums = [1,3,-1,-3,5,3,6,7], k = 3

輸出:
[3,3,5,5,6,7]

解釋:

  • 窗口 [1,3,-1] → 最大值 3
  • 窗口 [3,-1,-3] → 最大值 3
  • 窗口 [-1,-3,5] → 最大值 5
  • 窗口 [-3,5,3] → 最大值 5
  • 窗口 [5,3,6] → 最大值 6
  • 窗口 [3,6,7] → 最大值 7

二、常見解法分析

1. 暴力解法(Brute Force)

最直觀的方式是:每次滑動(dòng)窗口后,遍歷窗口中所有元素,找最大值。

func MaxSlidingWindowBrute(nums []int, k int) []int {
    var result []int
    for i := 0; i <= len(nums)-k; i++ {
        maxVal := nums[i]
        for j := i; j < i+k; j++ {
            if nums[j] > maxVal {
                maxVal = nums[j]
            }
        }
        result = append(result, maxVal)
    }
    return result
}

復(fù)雜度分析:

  • 時(shí)間復(fù)雜度:O(n*k)
  • 空間復(fù)雜度:O(1)

當(dāng) n 較大、k 較大時(shí),這種方法性能較差。例如 n=10^5, k=500 時(shí),暴力解法會(huì)非常慢。

2. 優(yōu)化解法:?jiǎn)握{(diào)隊(duì)列(Monotonic Queue)

為了提升效率,我們可以使用雙端隊(duì)列(Deque)實(shí)現(xiàn)一個(gè)單調(diào)遞減隊(duì)列。

核心思想

  • 隊(duì)列存下標(biāo),而非值;
  • 隊(duì)列內(nèi)下標(biāo)對(duì)應(yīng)的值保持從隊(duì)頭到隊(duì)尾遞減,這樣隊(duì)首元素就是當(dāng)前窗口最大值;
  • 每次新元素加入時(shí):
    • 移除隊(duì)尾小于當(dāng)前值的下標(biāo);
    • 將當(dāng)前下標(biāo)加入隊(duì)尾;
  • 檢查隊(duì)首是否超出窗口范圍(deque[0] <= i - k),如果是則彈出。

這種方式保證了每個(gè)元素最多進(jìn)出隊(duì)列一次,整體時(shí)間復(fù)雜度為 O(n)。

三、Go語言代碼實(shí)現(xiàn)(單調(diào)隊(duì)列法)

package main

import (
    "fmt"
)

// MaxSlidingWindow 求解滑動(dòng)窗口最大值
func MaxSlidingWindow(nums []int, k int) []int {
    if len(nums) == 0 || k == 0 {
        return []int{}
    }

    var result []int
    deque := []int{} // 存儲(chǔ)下標(biāo)

    for i, v := range nums {
        // 1. 移除隊(duì)尾比當(dāng)前元素小的下標(biāo)
        for len(deque) > 0 && nums[deque[len(deque)-1]] < v {
            deque = deque[:len(deque)-1]
        }
        // 2. 添加當(dāng)前元素下標(biāo)
        deque = append(deque, i)

        // 3. 移除超出窗口范圍的隊(duì)首下標(biāo)
        if deque[0] <= i-k {
            deque = deque[1:]
        }

        // 4. 當(dāng)窗口形成后,將隊(duì)首對(duì)應(yīng)的值加入結(jié)果
        if i >= k-1 {
            result = append(result, nums[deque[0]])
        }
    }

    return result
}

func main() {
    nums := []int{1, 3, -1, -3, 5, 3, 6, 7}
    k := 3
    fmt.Println(MaxSlidingWindow(nums, k)) // [3 3 5 5 6 7]
}

四、關(guān)鍵步驟詳解

  • 隊(duì)列存下標(biāo)而非值
    • 方便判斷是否超出窗口范圍;
    • 通過 nums[deque[0]] 獲取最大值。
  • 保持遞減順序
    • 只有比當(dāng)前值大的元素才可能在未來成為最大值;
    • 小于當(dāng)前值的元素直接被淘汰。
  • 滑動(dòng)與淘汰
    • 每次滑動(dòng)都要檢查隊(duì)首是否還在窗口內(nèi);
    • 淘汰不在窗口范圍的下標(biāo)。

五、復(fù)雜度分析

  • 時(shí)間復(fù)雜度:O(n)
    每個(gè)元素最多被加入和移出隊(duì)列一次。
  • 空間復(fù)雜度:O(k)
    隊(duì)列最多存儲(chǔ) k 個(gè)下標(biāo)。

六、工程應(yīng)用場(chǎng)景

  • 系統(tǒng)性能監(jiān)控
    • 在固定時(shí)間窗口內(nèi)找CPU利用率的峰值。
  • 金融數(shù)據(jù)分析
    • 計(jì)算股票價(jià)格的滑動(dòng)最大值,用于趨勢(shì)判斷。
  • 信號(hào)處理
    • 檢測(cè)信號(hào)峰值,常用于音頻分析、網(wǎng)絡(luò)流量監(jiān)控。

七、常見變種

  • 滑動(dòng)窗口最小值:只需將單調(diào)遞減隊(duì)列改為遞增隊(duì)列。
  • 滑動(dòng)窗口平均值/中位數(shù):需要更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)(如堆、平衡樹)。
  • 二維滑動(dòng)窗口最大值:可擴(kuò)展至圖像處理,如卷積操作。

八、測(cè)試與驗(yàn)證

我們可以編寫單元測(cè)試:

func TestMaxSlidingWindow(t *testing.T) {
    tests := []struct {
        nums []int
        k    int
        want []int
    }{
        {[]int{1,3,-1,-3,5,3,6,7}, 3, []int{3,3,5,5,6,7}},
        {[]int{9,10,9,-7,-4,-8,2,-6}, 5, []int{10,10,9,2}},
    }

    for _, tt := range tests {
        got := MaxSlidingWindow(tt.nums, tt.k)
        if !reflect.DeepEqual(got, tt.want) {
            t.Errorf("nums=%v k=%d got=%v want=%v", tt.nums, tt.k, got, tt.want)
        }
    }
}

九、總結(jié)

  • 滑動(dòng)窗口最大值問題是經(jīng)典的單調(diào)隊(duì)列應(yīng)用;
  • 暴力解法易實(shí)現(xiàn)但性能低;
  • 單調(diào)隊(duì)列解法能在 O(n) 時(shí)間內(nèi)解決問題,適合大數(shù)據(jù)場(chǎng)景;
  • 掌握該技巧有助于解決其他類似的區(qū)間統(tǒng)計(jì)問題。

 到此這篇關(guān)于Go語言滑動(dòng)窗口最大值的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Go語言滑動(dòng)窗口最大值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 用GO實(shí)現(xiàn)IP門禁優(yōu)化網(wǎng)絡(luò)流量管理

    用GO實(shí)現(xiàn)IP門禁優(yōu)化網(wǎng)絡(luò)流量管理

    這篇文章主要為大家介紹了用GO實(shí)現(xiàn)IP門禁優(yōu)化網(wǎng)絡(luò)流量管理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • GoLang之使用Context控制請(qǐng)求超時(shí)的實(shí)現(xiàn)

    GoLang之使用Context控制請(qǐng)求超時(shí)的實(shí)現(xiàn)

    這篇文章主要介紹了GoLang之使用Context控制請(qǐng)求超時(shí)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Go語言切片(Slice)深度剖析與應(yīng)用實(shí)戰(zhàn)

    Go語言切片(Slice)深度剖析與應(yīng)用實(shí)戰(zhàn)

    在Go語言中,切片(Slice)是一種非常強(qiáng)大且靈活的數(shù)據(jù)結(jié)構(gòu),它基于數(shù)組但又提供了動(dòng)態(tài)調(diào)整大小的能力,本文將結(jié)合實(shí)際案例,詳細(xì)介紹Go語言中切片的聲明、初始化、操作、擴(kuò)容等用法,需要的朋友可以參考下
    2024-09-09
  • Go利用反射reflect實(shí)現(xiàn)獲取接口變量信息

    Go利用反射reflect實(shí)現(xiàn)獲取接口變量信息

    反射是通過實(shí)體對(duì)象獲取反射對(duì)象(Value、Type),然后可以操作相應(yīng)的方法。本文將利用Go語言中的反射reflect實(shí)現(xiàn)獲取接口變量信息,需要的可以參考一下
    2022-05-05
  • docker如何安裝部署golang應(yīng)用程序

    docker如何安裝部署golang應(yīng)用程序

    這篇文章主要為大家介紹了docker如何安裝部署golang應(yīng)用程序詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • go語言通過管道連接兩個(gè)命令行進(jìn)程的方法

    go語言通過管道連接兩個(gè)命令行進(jìn)程的方法

    這篇文章主要介紹了go語言通過管道連接兩個(gè)命令行進(jìn)程的方法,實(shí)例分析了Go語言操作命令行進(jìn)程的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • GoLang調(diào)用鏈可視化go-callvis使用介紹

    GoLang調(diào)用鏈可視化go-callvis使用介紹

    與鏈路追蹤(Tracing)不同,Tracing關(guān)注復(fù)雜的分布式環(huán)境中各個(gè)服務(wù)節(jié)點(diǎn)間的調(diào)用關(guān)系,主要用于服務(wù)治理。而我們本次探索的代碼調(diào)用鏈路則是代碼方法級(jí)別的調(diào)用關(guān)系,主要用于代碼設(shè)計(jì)
    2023-02-02
  • golang結(jié)構(gòu)化日志slog的用法簡(jiǎn)介

    golang結(jié)構(gòu)化日志slog的用法簡(jiǎn)介

    日志是任何軟件的重要組成部分,Go?提供了一個(gè)內(nèi)置日志包(slog),在本文中,小編將簡(jiǎn)單介紹一下slog包的功能以及如何在?Go?應(yīng)用程序中使用它,感興趣的可以了解下
    2023-09-09
  • Go語言接口的嵌套的具體使用

    Go語言接口的嵌套的具體使用

    在Go語言中,不僅結(jié)構(gòu)體與結(jié)構(gòu)體之間可以嵌套,接口與接口間也可以通過嵌套創(chuàng)造出新的接口,本文主要介紹了Go語言接口的嵌套的具體使用,感興趣的可以了解一下
    2023-04-04
  • golang實(shí)現(xiàn)webgis后端開發(fā)的步驟詳解

    golang實(shí)現(xiàn)webgis后端開發(fā)的步驟詳解

    這篇文章主要介紹如何用golang結(jié)合postgis數(shù)據(jù)庫(kù),使用gin、grom框架實(shí)現(xiàn)后端的MVC的接口搭建,文中有詳細(xì)的流程步驟及代碼示例,需要的朋友可以參考下
    2023-06-06

最新評(píng)論