LeetCode算法日記 - Day 11: 尋找峰值、山脈數組的峰頂索引

目錄

1. 尋找峰值

1.1 題目解析

1.2 解法

1.3 代碼實現

2. 山脈數組

2.1 題目解析

2.2 解法

2.3 代碼實現


1. 尋找峰值

162. 尋找峰值 - 力扣(LeetCode)

峰值元素是指其值嚴格大于左右相鄰值的元素。

給你一個整數數組?nums,找到峰值元素并返回其索引。數組可能包含多個峰值,在這種情況下,返回?任何一個峰值?所在位置即可。

你可以假設?nums[-1] = nums[n] = -∞?。

你必須實現時間復雜度為?O(log n)?的算法來解決此問題。

示例 1:

輸入:nums = [1,2,3,1]
輸出:2
解釋:3 是峰值元素,你的函數應該返回其索引 2。

示例?2:

輸入:nums = [1,2,1,3,5,6,4]輸出:1 或 5 
解釋:你的函數可以返回索引 1,其峰值元素為 2;或者返回索引 5, 其峰值元素為 6。

提示:

  • 1 <= nums.length <= 1000
  • -231 <= nums[i] <= 231 - 1
  • 對于所有有效的?i?都有?nums[i] != nums[i + 1]

1.1 題目解析

  • 目標:在“嚴格先升后降”的山脈數組中找到唯一峰頂下標 i,滿足
    arr[0] < … < arr[i-1] < arr[i] > arr[i+1] > … > arr[n-1]。

  • 關鍵結構(可二分的二段性):定義性質 P(k) := arr[k] > arr[k-1](是否還在上坡)。 在區間 k ∈ [1, n-2] 上,P(k) 呈先真后假:峰頂及其左側為真,峰頂右側為假。 因此問題等價于:在 [1, n-2] 中找“最后一個使 P(k) 為真”的位置 → 即峰頂。

  • 搜索區間:為避免越界并且不丟解,取 [1, n-2](峰不在兩端,且要訪問 k-1)。

  • 收斂策略:配合“上中位數”與單側保留(上坡保留 mid),保證每輪縮小區間,最終 left == right。

  • 復雜度:時間 O(log n),空間 O(1)。

1.2 解法

i)對 P(k) := arr[k] > arr[k-1] 做“最后一個真”的二分查找

ii)若 arr[mid] > arr[mid-1](上坡/在峰左側或即將到峰),峰一定在 [mid, right],令 left = mid(保留 mid)。

iii)否則(下坡),峰一定在 [left, mid-1],令 right = mid - 1。

iiii)用上中位數避免死循環;終止時 left == right 即峰頂。

正確性要點

  • 不變量:每輪后峰頂始終在 [left, right]。

  • 收斂性:上中位數 + 上坡時 left = mid 保證區間嚴格縮小。

  • 復雜度:O(log n) / O(1)。

1.3 代碼實現

class Solution {public int peakIndexInMountainArray(int[] arr) {int left = 1, right = arr.length - 2; // 峰不在兩端,且要用到 mid-1while (left < right) {int mid = left + (right - left + 1) / 2; // 上中位數if (arr[mid] > arr[mid - 1]) {left = mid;          // 上坡:峰在 [mid, right]} else {right = mid - 1;     // 下坡:峰在 [left, mid-1]}}return left; // 即峰頂索引}
}

2. 山脈數組

852. 山脈數組的峰頂索引 - 力扣(LeetCode)

給定一個長度為?n?的整數?山脈?數組?arr?,其中的值遞增到一個?峰值元素?然后遞減。

返回峰值元素的下標。

你必須設計并實現時間復雜度為?O(log(n))?的解決方案。

示例 1:

輸入:arr = [0,1,0]
輸出:1

示例 2:

輸入:arr = [0,2,1,0]
輸出:1

示例 3:

輸入:arr = [0,10,5,2]
輸出:1

提示:

  • 3 <= arr.length <= 105
  • 0 <= arr[i] <= 106
  • 題目數據?保證?arr?是一個山脈數組

2.1 題目解析

  • 目標:在“嚴格先升后降”的數組(山脈數組)里找到峰頂下標 i,滿足 arr[0] < ... < arr[i-1] < arr[i] > arr[i+1] > ... > arr[n-1]。 峰值不在兩端,且一定唯一。

  • 本質:這是在上升段下降段的分界點上找位置。 設性質 P(k) := arr[k] > arr[k-1](“還在上坡”)。 在山脈數組中::

    • 峰頂及其左側:P(k) 恒為 (還在上坡或剛到頂的左側觀察點)。

    • 峰頂右側:P(k) 恒為 (已經下坡)。因而在區間 k ∈ [1, n-1],P(k) 呈現先真后假的“二段性”。我們要找的就是“最后一個使 P(k) 為真”的 k,它正是峰頂索引。

  • 為何能用二分:有了“先真后假”的結構,就能用二分在 P(k) 上做“找最后一個真”。這比線性掃描把復雜度從 O(n) 降到 O(log n)。

  • 邊界與越界:為了比較 arr[mid] 與 arr[mid-1],mid 最小得是 1; 又因為峰不在兩端,最大可到 n-2。 所以把搜索區間定為 [1, n-2],既不丟解也不越界。

  • 三種位置類型與判斷
    從“趨勢”角度看,mid 可能在:

    1. 上升段:arr[mid] > arr[mid-1](繼續上坡)

    2. 下降段:arr[mid] < arr[mid-1](已下坡)

    3. 峰頂:滿足 arr[mid] > arr[mid-1] && arr[mid] > arr[mid+1] 實際實現里只用“與左鄰比較”也足夠:峰頂在“與左鄰比較為真”的那一段的最右端,所以按“找最后一個真”就能把指針收斂到峰頂;無需顯式判斷右鄰。

2.2 解法

i)在閉區間 left = 1, right = n-2 上二分(峰不在兩端,且我們要用到 arr[mid-1])。

ii)取上中位數:mid = left + (right - left + 1) / 2。

iii)若 arr[mid] > arr[mid - 1](仍在上坡),則峰一定在 [mid, right],令 left = mid。

iiii)否則(已在下坡),峰一定在 [left, mid - 1],令 right = mid - 1。

iiiii)直到 left == right,即為峰頂索引,返回之。

正確性要點

  • 不變量:峰頂始終在 [left, right]。

    • 上坡保留 [mid, right] 不丟峰;

    • 下坡保留 [left, mid-1] 不丟峰。

  • 收斂性:選“上中位數”并在上坡時賦 left = mid,保證區間嚴格縮小,終將 left == right。

  • 復雜度:時間 O(log n),空間 O(1)。

2.3 代碼實現

class Solution {public int peakIndexInMountainArray(int[] arr) {int n = arr.length;int left = 1, right = n - 2; // 峰不在兩端,且需訪問 arr[mid-1]while (left < right) {int mid = left + (right - left + 1) / 2; // 上中位數if (arr[mid] > arr[mid - 1]) {// 上坡:峰在 [mid, right],保留 midleft = mid;} else {// 下坡:峰在 [left, mid-1],丟棄 midright = mid - 1;}}return left; // 或 right}
}

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

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

相關文章

Cherryusb UAC例程對接STM32 SAI播放音樂和錄音(下)=>USB+SAI+TX+RX+DMA控制WM8978播放和錄音實驗

1. 程序基本框架 整個程序框架, 與之前的一篇文章《Cherryusb UAC例程對接STM32內置ADC和DAC播放音樂和錄音(中)>UACSTM32 ADCDAC實現錄音和播放》基本一致, 只是這次將ADC和DAC替換成了SAI TX/RX。因此這里不再贅述了。2. sai_dma_wm8978_usb.c主程序的實現說明 在menuconf…

Docker運行python項目:使用Docker成功啟動FastAPI應用

根據昨天成功使用阿里云鏡像加速后&#xff0c;我是根據windows本地的python項目&#xff0c;直接傳到了centos&#xff0c;然后再導入到docker里面&#xff0c;然后進行運行&#xff0c;主要是發現運行的時候&#xff0c;老是提示一些庫的問題&#xff0c;還有就是一些python老…

PowerShell來關閉 Windows 安全中心

你可以使用 PowerShell 來關閉 Windows 安全中心的盾牌圖標&#xff08;通知&#xff09;。以下是幾種方法&#xff0c;包括禁用通知、關閉 Windows Defender&#xff08;不推薦&#xff09;或調整注冊表。方法 1&#xff1a;禁用 Windows 安全中心通知&#xff08;推薦&#x…

基于深度學習的老照片修復系統

背景隨著時間的推移&#xff0c;老照片可能會因褪色、損壞或曝光不當而影響其視覺質量。這些珍貴的影像承載著歷史和回憶&#xff0c;但由于物理損耗&#xff0c;它們的觀賞價值和可讀性逐漸下降。為了恢復這些照片的清晰度和色彩&#xff0c;本項目采用深度學習與先進的圖像處…

深入解析Tomcat目錄結構

Apache Tomcat 是一個強大的 Servlet 容器,它不僅支持 Java Servlet 和 JSP 技術,還提供了豐富的功能來幫助開發者構建和部署動態的 Web 應用。為了更好地理解和使用 Tomcat,了解其文件結構和組成部分是至關重要的。本文將深入探討 Tomcat 的目錄結構及其各個組件的作用。 …

專題:2025抖音電商與微短劇行業研究報告|附150+份報告PDF匯總下載

原文鏈接&#xff1a;https://tecdat.cn/?p43595 當618大促的硝煙散去&#xff0c;抖音電商的生態分化愈發刺眼&#xff1a;服飾內衣以27.5%的份額穩坐頭把交椅&#xff0c;而無數中小商家卻在“流量荒”中掙扎。這場看似繁榮的盛宴里&#xff0c;平臺規則如同無形的手&#x…

3.Ansible自動化之-編寫和運行playbook

3.Ansible編寫和運行 Playbook Playbook 介紹 如果把 Ansible 的ad-hoc命令比作 “一次性腳本”&#xff08;適合臨時執行單個簡單任務&#xff09;&#xff0c;那么Playbook就是 “可重復執行的程序”&#xff08;適合復雜、多步驟的管理流程&#xff09;。 舉個例子&#…

Vue實時刷新,比如我提交審核,審核頁面還需要點查詢才能看到最新數據

refreshTimer: null,lastRefreshTime: null}; }, created() {console.log(組件創建&#xff0c;初始化數據...);this.loadLatestData();this.setupAutoRefresh(); }, activated() {// 當使用keep-alive時&#xff0c;組件激活時刷新數據console.log(組件激活&#xff0c;刷新數…

Docker入門:容器化技術的第一堂課

Docker入門&#xff1a;容器化技術的第一堂課 &#x1f31f; 你好&#xff0c;我是 勵志成為糕手 &#xff01; &#x1f30c; 在代碼的宇宙中&#xff0c;我是那個追逐優雅與性能的星際旅人。 ? 每一行代碼都是我種下的星光&#xff0c;在邏輯的土壤里生長成璀璨的銀河&#…

【SLAM】不同相機模型及其常見的鏈式求導推導

【SLAM】不同相機模型及其常見的鏈式求導推導1. 魚眼相機模型鏈式求導1. 魚眼相機畸變模型2. 雅可比矩陣的推導畸變坐標相對于歸一化坐標的雅可比矩陣 Hdz/dznH_{dz/dzn}Hdz/dzn?畸變坐標相對于相機內參的雅可比矩陣 Hdz/dzetaH_{dz/dzeta}Hdz/dzeta?3. 注意4. 輸入輸出含義5…

【人工智能】本地部署 KTransformers并加載大模型筆記

博主未授權任何人或組織機構轉載博主任何原創文章&#xff0c;感謝各位對原創的支持&#xff01; 博主鏈接 本人就職于國際知名終端廠商&#xff0c;負責modem芯片研發。 在5G早期負責終端數據業務層、核心網相關的開發工作&#xff0c;目前牽頭6G技術研究。 博客內容主要圍繞…

TDengine IDMP 高級功能(3. 概念解釋)

枚舉集 為提升數據的可閱讀性&#xff0c;IDMP 為數據提供枚舉類型。您可以將一些整型數定義為一具有可讀性的字符串。與其他軟件一樣&#xff0c;您可以定義多個枚舉集&#xff0c;每個枚舉集可以有多個枚舉量。您可以增加、刪除、修改、查詢枚舉集與枚舉量。 但獨特的是&am…

CUDA 入門教程(GPT優化版)

學習路徑 一、環境準備與快速入門 搭建開發環境 ○ 安裝 CUDA Toolkit,適用于 Windows(如 Visual Studio)或 Linux,確保你的設備為 NVIDIA GPU 并支持 CUDA。(wholetomato.com) ○ 如果你偏好輕量工具,也可用 VS Code + Nsight 開發環境進行 CUDA 編程。(wholetomato.com)…

react項目性能優化的hook

前言&#xff1a;在項目中開發中&#xff0c;性能優化是很重要的&#xff0c;react有提供專門的hook&#xff0c;useMemo 和useCallback 這里說一說他們。區別&#xff1a;特性useMemouseCallback返回值緩存一個 值&#xff08;計算結果&#xff09;緩存一個 函數依賴變化時重新…

Docker(springcloud筆記第三期)

p.s.這是萌新自己自學總結的筆記&#xff0c;如果想學習得更透徹的話還是請去看大佬的講解 目錄鏡像與容器一些命令與鏡像命名規范數據卷自定義鏡像Dockerfile鏡像與容器 當我們利用Docker安裝應用時&#xff0c;Docker會自動搜索并下載應用鏡像(image),鏡像不僅包含應用本身&…

MySQL定時任務詳解 - Event Scheduler 事件調度器從基礎到實戰

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有堅忍不拔之志 &#x1f390; 個人CSND主頁——Micro麥可樂的博客 &#x1f425;《Docker實操教程》專欄以最新的Centos版本為基礎進行Docker實操教程&#xff0c;入門到實戰 &#x1f33a;《RabbitMQ》…

redis存儲原理與對象模型

redis中的不同線程 redis單線程是指什么&#xff1f; redis的所有命令處理都在同一個線程中完成 redis為什么采用單線程&#xff1f; redis中存在多種數據結構存儲value&#xff0c;如果采用多線程&#xff0c;加鎖會很復雜、加鎖力度不阿紅控制&#xff0c;同時&#xff0c…

基于微信小程序的家教服務平臺的設計與實現/基于asp.net/c#的家教服務平臺/基于asp.net/c#的家教管理系統

基于微信小程序的家教服務平臺的設計與實現/基于asp.net/c#的家教服務平臺/基于asp.net/c#的家教管理系統

安全審計-iptales防火墻設置

文章目錄一、iptales防火墻設置1.ip規則設置2.ip端口規則設置3.刪除規則4.INPUT默認設置5.ping、本地訪問規則6.保存還原規則7.查看清除規則一、iptales防火墻設置 1.ip規則設置 #允許ip訪問本服務器 iptables -I INPUT -s 192.168.205.129 -p tcp -j ACCEPT#允許某IP或某網段…

Linux小白加油站,第二周

1.grep命令中哪個選項可以忽略大小寫進行搜索?grep -i 2.如何用grep命令查找包含”error關鍵字的日志文件并返回文件名?grep -lr3.解釋grep命令中^f...d$這個表達式的含義^f&#xff1a;以f開頭..&#xff1a;任意兩個字符d$&#xff1a;以d結尾4.如何過濾掉文件中的注釋行以…