擺動序列:如何讓數組“上下起伏”地最長?

在這里插入圖片描述
在這里插入圖片描述

文章目錄

    • 摘要
    • 描述
    • 題解答案
    • 題解代碼分析
      • 代碼解析
    • 示例測試及結果
    • 時間復雜度
    • 空間復雜度
    • 總結

摘要

今天我們要聊的是 LeetCode 第 376 題 —— 擺動序列
題目的意思其實很有意思:如果一個序列里的相鄰差值能保持正負交替,就叫做“擺動”。比如 [1, 7, 4, 9, 2, 5],它就像過山車一樣,上下起伏,非常符合“擺動”的定義。

這道題的目標就是:從給定數組中找到最長的擺動子序列長度。
我會帶你先理解題意,再分析解法,最后用 Swift 寫出可運行的 Demo,并結合實際場景讓這個抽象的問題更容易理解。

描述

題目要求我們找到數組中最長的擺動子序列:

  • 如果相鄰兩個數的差嚴格正負交替,那么就是擺動序列。
  • 一個數字或者兩個不相等的數字也算擺動序列。
  • 允許我們刪掉一些數,但不能打亂順序。

比如:

  • [1, 7, 4, 9, 2, 5] → 差值是 (6, -3, 5, -7, 3),完全正負交替,長度就是 6。
  • [1, 17, 10, 13, 10, 16, 8] → 差值 (16, -7, 3, -3, 6, -8),長度是 7。
  • [1, 2, 3, 4, 5, 6, 7, 8, 9] → 最長只有兩個數,因為它一直是遞增,沒有“起伏”。

題解答案

這道題的本質是一個 動態規劃 + 貪心思想 的組合問題。
我們只需要關心當前“趨勢”:

  • 如果當前差值是正的,就意味著我們找到了一個“上升擺動”。
  • 如果當前差值是負的,就意味著我們找到了一個“下降擺動”。

于是,我們可以用兩個變量來動態記錄:

  • up[i] 表示以第 i 個元素結尾的最長上升擺動序列長度。
  • down[i] 表示以第 i 個元素結尾的最長下降擺動序列長度。

狀態轉移關系:

  • 如果 nums[i] > nums[i-1]

    • up[i] = down[i-1] + 1
  • 如果 nums[i] < nums[i-1]

    • down[i] = up[i-1] + 1
  • 如果相等,啥也不變。

最后結果就是 max(up[n-1], down[n-1])

這個邏輯其實就像我們生活中“情緒波動”一樣:

  • 當你心情一直很嗨(遞增),突然遇到挫折(下降),這時候才算一次“擺動”;
  • 當你心情很低落(下降),突然遇到好事(上升),又算一次“擺動”。
    如果一直高歌猛進或者持續低迷,就沒有擺動。

題解代碼分析

下面我們用 Swift 來實現:

import Foundationclass Solution {func wiggleMaxLength(_ nums: [Int]) -> Int {if nums.count < 2 { return nums.count }var up = 1var down = 1for i in 1..<nums.count {if nums[i] > nums[i - 1] {up = down + 1} else if nums[i] < nums[i - 1] {down = up + 1}}return max(up, down)}
}

代碼解析

  1. 初始化
    如果數組長度小于 2,直接返回數組長度。因為一個數或兩個不相等的數就是擺動序列。

  2. 定義變量
    updown 初始值都設為 1。代表至少可以形成一個單獨的數字序列。

  3. 遍歷數組

    • 如果當前數比前一個大,說明找到一個上升趨勢,于是 up = down + 1
    • 如果當前數比前一個小,說明找到一個下降趨勢,于是 down = up + 1
    • 如果相等,不做任何更新。
  4. 返回結果
    最后返回 max(up, down),即最長的擺動子序列。

示例測試及結果

我們來跑幾個例子驗證一下:

let solution = Solution()print(solution.wiggleMaxLength([1, 7, 4, 9, 2, 5]))  
// 輸出: 6print(solution.wiggleMaxLength([1, 17, 5, 10, 13, 15, 10, 5, 16, 8]))  
// 輸出: 7print(solution.wiggleMaxLength([1, 2, 3, 4, 5, 6, 7, 8, 9]))  
// 輸出: 2

輸出結果:

6
7
2

結果和題目示例完全一致。

時間復雜度

我們只遍歷了一次數組,每個元素只做了常數操作。
因此時間復雜度是 O(n)

空間復雜度

我們只用了常數個變量 updown,不需要額外存儲數組。
因此空間復雜度是 O(1)

總結

這道題的關鍵點在于:

  • 不要陷入“暴力枚舉所有子序列”的陷阱。那樣復雜度太高。
  • 只需要用兩個變量跟蹤“上升”和“下降”的最長長度,就能搞定。

從實際場景來看,它就像分析“股市行情”或“人的情緒波動”:

  • 如果股價總是漲(或總是跌),最長的擺動長度就很小。
  • 如果股價能反復起伏,擺動序列就會變長。
    所以這個算法思路不僅能解決題目,還能幫助我們理解“變化趨勢”在數據分析里的意義。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96478.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96478.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96478.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

玩轉Docker | 使用Docker部署KissLists任務管理工具

玩轉Docker | 使用Docker部署KissLists任務管理工具 前言 一、KissLists介紹 KissLists簡介 KissLists核心特點 KissLists注意事項 二、系統要求 環境要求 環境檢查 Docker版本檢查 檢查操作系統版本 三、部署KissLists服務 下載KissLists鏡像 編輯部署文件 創建容器 檢查容器狀…

【滑動窗口】C++高效解決子數組問題

個人主頁 &#xff1a; zxctscl 專欄 【C】、 【C語言】、 【Linux】、 【數據結構】、 【算法】 如有轉載請先通知 文章目錄前言1 209. 長度最小的子數組1.1 分析1.2 代碼2 3. 無重復字符的最長子串2.1 分析2.2 代碼3 1004. 最大連續1的個數 III3.1 分析3.2 代碼4 1658. 將 x …

[rStar] 搜索代理(MCTS/束搜索)

第2章&#xff1a;搜索代理(MCTS/束搜索) 歡迎回到rStar 在前一章中&#xff0c;我們學習了求解協調器&#xff0c;它就像是解決數學問題的項目經理。 它組織整個過程&#xff0c;但本身并不進行"思考"&#xff0c;而是將這項工作委托給其專家團隊。 今天&#x…

Electron 核心模塊速查表

為了更全面地覆蓋常用 API&#xff0c;以下表格補充了更多實用方法和場景化示例&#xff0c;同時保持格式清晰易讀。 一、主進程模塊 模塊名核心用途關鍵用法 示例注意事項app應用生命周期管理? 退出應用&#xff1a;app.quit()? 重啟應用&#xff1a;app.relaunch() 后需…

Qt C++ 圖形繪制完全指南:從基礎到進階實戰

Qt C 圖形繪制完全指南&#xff1a;從基礎到進階實戰 前言 Qt框架提供了強大的2D圖形繪制能力&#xff0c;通過QPainter類及其相關組件&#xff0c;開發者可以輕松實現各種復雜的圖形繪制需求。本文將系統介紹Qt圖形繪制的核心技術&#xff0c;并通過實例代碼演示各種繪制技巧…

二分搜索邊界問題

在使用二分搜索的時候&#xff0c;更新條件不總是相同&#xff0c;雖然說使用bS目的就是為了target&#xff0c;但也有如下幾種情況&#xff1a;求第一個target的索引求第一個>target的索引求第一個>target的索引求最后一個target的索引求最后一個<target的索引求最后…

【springboot+vue3】博客論壇管理系統(源碼+文檔+調試+基礎修改+答疑)

目錄 一、整體目錄&#xff1a; 項目包含源碼、調試、修改教程、調試教程、講解視頻、開發文檔&#xff08;項目摘要、前言、技術介紹、可行性分析、流程圖、結構圖、ER屬性圖、數據庫表結構信息、功能介紹、測試致謝等約1萬字&#xff09; 二、運行截圖 三、代碼部分&…

20250907_梳理異地備份每日自動巡檢Python腳本邏輯流程+安裝Python+PyCharm+配置自動運行

一、邏輯流程(autocheckbackup.py在做什么) 1.連接Linux服務器 用 paramiko 登錄你配置的 Linux 服務器(10.1.3.15, 10.1.3.26),進入指定目錄(如 /home, /backup/mes),遞歸列出文件。 采集到的信息:服務器IP、目錄、數據庫名稱、文件名、大小、修改時間。 2.連接Wind…

terraform-state詳解

一、Treeaform-state的作用 Terraform-state是指Terroform的狀態&#xff0c;是terraform不可缺少的生命周期元素。本質上來講&#xff0c;terraform狀態是你的基礎設施配置的元數據存儲庫&#xff0c;terraform會把它管理的資源狀態保存在一個狀態文件里。 默認情況下&#xf…

四、kubernetes 1.29 之 Pod 生命周期

一、概述當容器與 pause 容器共享網絡&#xff08;Network&#xff09;、IPC&#xff08;進程間通信&#xff09;和 PID&#xff08;進程命名空間&#xff09;后&#xff0c;二者形成了一種緊密的 "共享命名空間" 關系&#xff0c;共同構成了 Kubernetes 中 "Po…

AI與環保:禮貌用語背后的能源挑戰與解決方案

程序員的技術管理推薦閱讀 窄化效應&#xff1a;程序員與管理者的隱形情緒陷阱 從“激勵”到“保健”&#xff1a;80后與90后程序員&#xff0c;到底想要什么&#xff1f; 從“激勵”到“保健”&#xff1a;80后與90后程序員&#xff0c;到底想要什么&#xff1f; 場景引入&…

OpenCV C++ 特征提取:從角點檢測到對象識別

特征提取是計算機視覺的核心技術,通過識別圖像中具有代表性的關鍵點及其描述信息,實現圖像匹配、對象識別、姿態估計等高級任務。本章將系統講解從基礎的圖像金字塔、角點檢測,到復雜的 ORB 和 SIFT 特征提取與匹配,最終實現基于特征的對象檢測完整流程。 一、圖像金字塔 …

Codeforces Round 1049 (Div. 2) D題題解記錄

大致題意&#xff1a;給定nnn個區間(li,ri)(l_i,r_i)(li?,ri?)。每次選取兩個尚未被標記的區間(l1,r1)(l_1,r_1)(l1?,r1?)與(l2,r2)(l_2,r_2)(l2?,r2?)&#xff0c;使得他們均被標記&#xff0c;同時可以任選x∈[l1,r1]&#xff0c;y∈[l2,r2]x\in[l_1,r_1]&#xff0c;y…

《WINDOWS 環境下32位匯編語言程序設計》第15章 注冊表和INI文件

15.1 注冊表和INI文件簡介在一個操作系統中&#xff0c;無論是操作系統本身還是運行于其中的大部分應用程序&#xff0c;都需要使用某種方式保存配置信息。在DOS系統中&#xff0c;配置信息往往是軟件的開發者根據自己的喜好用各種途徑加以保存的&#xff0c;比如在磁盤上面寫一…

JDK 17、OpenJDK 17、Oracle JDK 17 的說明

Java生態系統的核心概念&#xff1a;簡單來說&#xff1a;JDK 17 是一個標準規范&#xff0c;定義了Java開發工具包第17個長期支持版應該包含什么功能。openjdk-17-jdk 是一個具體的實現&#xff0c;是遵循上述規范、由OpenJDK社區提供的開源軟件包。下面我們通過一個表格和詳細…

手寫MyBatis第58彈:如何優雅輸出可執行的SQL語句--深入理解MyBatis日志機制:

&#x1f942;(???)您的點贊&#x1f44d;?評論&#x1f4dd;?收藏?是作者創作的最大動力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;點贊&#x1f44d;收藏??留言&#x1f4dd;歡迎留言討論 &#x1f525;&#x1f525;&…

Spring Boot 監控實戰:集成 Prometheus 與 Grafana,打造全方位監控體系

前言 在當今微服務架構盛行的時代&#xff0c;應用程序的監控變得尤為重要。Spring Boot 作為廣泛使用的微服務框架&#xff0c;其監控需求也日益增加。Prometheus 和 Grafana 作為開源監控領域的佼佼者&#xff0c;為 Spring Boot 應用提供了強大的監控能力。本文將詳細介紹如…

JS中的多線程——Web Worker

眾所周知&#xff0c;JavaScript 是單線程運行的&#xff08;至于為什么是單線程可以看一下這篇文章——事件循環機制&#xff09;&#xff0c;當瀏覽器主線程被大量計算任務阻塞時&#xff0c;頁面就會出現明顯的卡頓現象。Web Worker 提供了在獨立線程中運行 JavaScript 的能…

【SQL注入】延時盲注

sleep(n)??: 核心延時函數。使數據庫程序暫停 n秒。??if(condition, true_expr, false_expr)??: 條件判斷函數。如果 condition為真&#xff0c;執行 true_expr&#xff0c;否則執行 false_expr。??用于將延時與判斷條件綁定??。??mid(a, b, c)??: 字符串截取函數…

IntelliJ IDEA 2025.1 Java Stream Debugger 快速使用指南

1. 功能概覽 Java Stream Debugger 提供 Trace Current Stream Chain 功能&#xff0c;用來在調試時分析和可視化 Stream 操作鏈。 主要用途&#xff1a; 在運行時查看流操作鏈的每一步輸出找出 map/filter 等操作的問題避免手動加 peek() 打印調試2. 使用入口 在 IDEA 2025.1 …