LeetCode 2297. 跳躍游戲 VIII(中等)

題目描述

給定一個長度為 n 的下標從?0?開始的整數數組?nums。初始位置為下標?0。當?i < j?時,你可以從下標?i?跳轉到下標?j:

  • 對于在?i < k < j?范圍內的所有下標?k?有?nums[i] <= nums[j]?和?nums[k] < nums[i]?, 或者
  • 對于在?i < k < j?范圍內的所有下標?k?有?nums[i] > nums[j]?和?nums[k] >= nums[i]?。

你還得到了一個長度為?n?的整數數組?costs,其中?costs[i]?表示跳轉下標?i?的代價。

返回跳轉到下標?n - 1?的最小代價。

示例 1:

輸入: nums = [3,2,4,4,1], costs = [3,7,6,4,2]
輸出: 8
解釋: 從下標 0 開始。
- 以 costs[2]= 6 的代價跳轉到下標 2。
- 以 costs[4]= 2 的代價跳轉到下標 4。
總代價是 8。可以證明,8 是所需的最小代價。
另外兩個可能的路徑是:下標 0 -> 1 -> 4 和下標 0 -> 2 -> 3 -> 4。
它們的總代價分別為9和12。

示例?2:

輸入: nums = [0,1,2], costs = [1,1,1]
輸出: 2
解釋: 從下標 0 開始。
- 以 costs[1] = 1 的代價跳轉到下標 1。
- 以 costs[2] = 1 的代價跳轉到下標 2。
總代價是 2。注意您不能直接從下標 0 跳轉到下標 2,因為 nums[0] <= nums[1]。

解釋:

  • n == nums.length == costs.length
  • 1 <= n <= 10^5
  • 0 <= nums[i], costs[i] <= 10^5

問題分析

這道題是跳躍游戲系列中的一道具有挑戰性的題目。關鍵在于理解跳躍條件:

跳躍條件解析:

  • 條件一:?nums[i] <=?nums[j]?且中間所有?nums[k]?< nums[i]

    • 含義:從位置i跳到右側第一個?≥ nums[i]?的位置

    • 對應:單調遞減棧(維護一個從棧底到棧頂遞減的序列)

  • 條件二:?nums[i] > nums[j]?且中間所有?nums[k] >=?nums[i]

    • 含義:從位置i跳到右側第一個?< nums[i]?的位置

    • 對應:單調遞增棧(維護一個從棧底到棧頂遞增的序列)

這兩個條件實際上是互補的,可以用單調棧來高效處理。


解題思路

單調棧?+ 動態規劃

核心思想:

  1. 使用兩個單調棧分別處理兩種跳躍條件
  2. 用動態規劃記錄到達每個位置的最小代價
  3. 從左到右遍歷,動態更新可達位置的最小代價

算法步驟:

  • 初始化?dp[i]?表示到達位置 i?的最小代價,dp[0] =?0
  • 維護兩個單調棧:
    • stack1:處理條件一(單調遞減棧)
    • stack2:處理條件二(單調遞增棧)
  • 對每個位置 j,檢查能從哪些位置跳到?j,并更新最小代價

算法過程

輸入:?nums = [3,2,4,4,1],?costs = [3,7,6,4,2]

初始狀態

位置:    0  1  2  3  4
nums:   [3, 2, 4, 4, 1]
costs:  [3, 7, 6, 4, 2]
dp:     [0, ∞, ∞, ∞, ∞]stack1: []  (單調遞減棧 - 處理條件一)
stack2: []  (單調遞增棧 - 處理條件二)

步驟1:處理位置0 (nums[0] = 3)

當前位置 j = 0, nums[0] = 3stack1操作:
- 棧為空,直接入棧
- stack1: [0]stack2操作:
- 棧為空,直接入棧  
- stack2: [0]dp狀態:[0, ∞, ∞, ∞, ∞]

步驟2:處理位置1 (nums[1]?= 2)

當前位置 j = 1, nums[1] = 2stack1操作(條件一):
- nums[stack1.top()] = nums[0] = 3 > nums[1] = 2
- 不滿足 nums[i] <= nums[j],不彈出
- stack1: [0, 1]stack2操作(條件二):
- nums[stack2.top()] = nums[0] = 3 > nums[1] = 2 ?
- 彈出位置0,更新 dp[1] = min(∞, dp[0] + costs[1]) = min(∞, 0 + 7) = 7
- 將位置1入棧
- stack2: [1]dp狀態:[0, 7, ∞, ∞, ∞]跳躍路徑:0 → 1 (代價7)

步驟3:處理位置2 (nums[2]?= 4)

當前位置 j = 2, nums[2] = 4stack1操作(條件一):
- nums[1] = 2 <= nums[2] = 4 ?,彈出位置1dp[2] = min(∞, dp[1] + costs[2]) = min(∞, 7 + 6) = 13
- nums[0] = 3 <= nums[2] = 4 ?,彈出位置0  dp[2] = min(13, dp[0] + costs[2]) = min(13, 0 + 6) = 6
- 將位置2入棧
- stack1: [2]stack2操作(條件二):
- nums[1] = 2 < nums[2] = 4,不滿足條件二,不彈出
- 將位置2入棧
- stack2: [1, 2]dp狀態:[0, 7, 6, ∞, ∞]跳躍路徑:0 → 2 (代價6) 或 0 → 1 → 2 (代價13)
最優:0 → 2 (代價6)

步驟4:處理位置3 (nums[3] =?4)

當前位置 j = 3, nums[3] = 4stack1操作(條件一):
- nums[2] = 4 <= nums[3] = 4 ?,彈出位置2dp[3] = min(∞, dp[2] + costs[3]) = min(∞, 6 + 4) = 10
- 將位置3入棧
- stack1: [3]stack2操作(條件二):
- nums[2] = 4 不大于 nums[3] = 4,不彈出
- 將位置3入棧
- stack2: [1, 2, 3]dp狀態:[0, 7, 6, 10, ∞]跳躍路徑:0 → 2 → 3 (代價10)

步驟5:處理位置4?(nums[4] = 1)

當前位置 j = 4, nums[4] = 1stack1操作(條件一):
- nums[3] = 4 > nums[4] = 1,不滿足條件一,不彈出
- 將位置4入棧
- stack1: [3, 4]stack2操作(條件二):
- nums[3] = 4 > nums[4] = 1 ?,彈出位置3dp[4] = min(∞, dp[3] + costs[4]) = min(∞, 10 + 2) = 12
- nums[2] = 4 > nums[4] = 1 ?,彈出位置2dp[4] = min(12, dp[2] + costs[4]) = min(12, 6 + 2) = 8
- nums[1] = 2 > nums[4] = 1 ?,彈出位置1dp[4] = min(8, dp[1] + costs[4]) = min(8, 7 + 2) = 9
- 最終 dp[4] = 8
- stack2: [4]dp狀態:[0, 7, 6, 10, 8]跳躍路徑:0 → 2 → 4 (代價8)

最優路徑

最終答案:dp[4] = 8最優路徑:0 → 2 → 4
詳細分析:
- 從位置0跳到位置2:滿足條件一 (nums[0]=3 <= nums[2]=4,中間nums[1]=2 < nums[0]=3)
- 從位置2跳到位置4:滿足條件二 (nums[2]=4 > nums[4]=1,中間nums[3]=4 >= nums[2]=4)
- 總代價:costs[2] + costs[4] = 6 + 2 = 8

詳細代碼實現

Java?實現

class Solution {public long minCost(int[] nums, int[] costs) {int n = nums.length;long[] dp = new long[n];// 初始化dp數組Arrays.fill(dp, Long.MAX_VALUE);dp[0] = 0;  // 起始位置代價為0// 兩個單調棧Deque<Integer> stack1 = new ArrayDeque<>();  // 處理條件一Deque<Integer> stack2 = new ArrayDeque<>();  // 處理條件二for (int j = 0; j < n; j++) {// 處理條件一:nums[i] <= nums[j] 且中間元素都小于 nums[i]// 單調遞減棧,當遇到更大的元素時彈出while (!stack1.isEmpty() && nums[stack1.peek()] <= nums[j]) {int i = stack1.pop();dp[j] = Math.min(dp[j], dp[i] + costs[j]);}stack1.push(j);// 處理條件二:nums[i] > nums[j] 且中間元素都大于等于 nums[i]// 單調遞增棧,當遇到更小的元素時彈出while (!stack2.isEmpty() && nums[stack2.peek()] > nums[j]) {int i = stack2.pop();dp[j] = Math.min(dp[j], dp[i] + costs[j]);}stack2.push(j);}return dp[n - 1];}
}

C# 實現

public class Solution {public long MinCost(int[] nums, int[] costs) {int n = nums.Length;long[] dp = new long[n];// 初始化dp數組for (int i = 0; i < n; i++) {dp[i] = long.MaxValue;}dp[0] = 0;  // 起始位置代價為0// 兩個單調棧Stack<int> stack1 = new Stack<int>();  // 處理條件一Stack<int> stack2 = new Stack<int>();  // 處理條件二for (int j = 0; j < n; j++) {// 處理條件一:nums[i] <= nums[j] 且中間元素都小于 nums[i]while (stack1.Count > 0 && nums[stack1.Peek()] <= nums[j]) {int i = stack1.Pop();dp[j] = Math.Min(dp[j], dp[i] + costs[j]);}stack1.Push(j);// 處理條件二:nums[i] > nums[j] 且中間元素都大于等于 nums[i]while (stack2.Count > 0 && nums[stack2.Peek()] > nums[j]) {int i = stack2.Pop();dp[j] = Math.Min(dp[j], dp[i] + costs[j]);}stack2.Push(j);}return dp[n - 1];}
}

時間復雜度和空間復雜度

  • 時間復雜度:O(n)?- 每個元素最多入棧和出棧一次
  • 空間復雜度:O(n)?- dp數組和兩個棧的空間

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

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

相關文章

【前端】緩存相關

本知識頁參考&#xff1a;https://zhuanlan.zhihu.com/p/586060532 1. 概述 1.1 應用場景 靜態資源 場景&#xff1a;圖片、CSS、JS 文件等靜態資源實現&#xff1a;使用 HTTP 緩存控制頭&#xff0c;或者利用 CDN 進行邊緣緩存 數據緩存 場景&#xff1a;請求的返回結果實現…

獵板硬金鍍層厚度:高頻通信領域的性能分水嶺

在 5G 基站、毫米波雷達等高頻場景中&#xff0c;硬金鍍層厚度的選擇直接決定了 PCB 的信號完整性與長期可靠性。獵板硬金工藝&#xff1a; 1.8μm 金層搭配羅杰斯 4350B 基材的解決方案&#xff0c;在 10GHz 頻段實現插入損耗&#xff1c;0.15dB/cm&#xff0c;較常規工藝降低…

第35次CCF計算機軟件能力認證-5-木板切割

原題鏈接&#xff1a; TUOJ 我自己寫的35分正確但嚴重超時的代碼 #include <bits/stdc.h> using namespace std; int main() {int n, m, k;cin >> n >> m >> k;vector<unordered_map<int, int>> mp(2);int y;for (int i 1; i < n; …

【藍橋杯】包子湊數

包子湊數 題目描述 小明幾乎每天早晨都會在一家包子鋪吃早餐。他發現這家包子鋪有 NN 種蒸籠&#xff0c;其中第 ii 種蒸籠恰好能放 AiAi? 個包子。每種蒸籠都有非常多籠&#xff0c;可以認為是無限籠。 每當有顧客想買 XX 個包子&#xff0c;賣包子的大叔就會迅速選出若干…

pikachu通關教程-目錄遍歷漏洞(../../)

目錄遍歷漏洞也可以叫做信息泄露漏洞、非授權文件包含漏洞等. 原理:目錄遍歷漏洞的原理比較簡單&#xff0c;就是程序在實現上沒有充分過濾用戶輸入的../之類的目錄跳轉符&#xff0c;導致惡意用戶可以通過提交目錄跳轉來遍歷服務器上的任意文件。 這里的目錄跳轉符可以是../…

[概率論基本概念4]什么是無偏估計

關鍵詞&#xff1a;Unbiased Estimation 一、說明 對于無偏和有偏估計&#xff0c;需要了解其敘事背景&#xff0c;是指整體和抽樣的關系&#xff0c;也就是說整體的敘事是從理論角度的&#xff0c;而估計器原理是從實踐角度說事&#xff1b;為了表明概率理論&#xff08;不可…

面試題——計算機網絡:HTTP和HTTPS的區別?

HTTP&#xff08;HyperText Transfer Protocol&#xff09;&#xff1a;作為互聯網上應用最廣泛的網絡通信協議&#xff0c;HTTP是基于TCP/IP協議族的應用層協議。它采用標準的請求-響應模式進行通信&#xff0c;通過簡潔的報文格式&#xff08;包含請求行、請求頭、請求體等&a…

uni-app學習筆記十九--pages.json全局樣式globalStyle設置

pages.json 頁面路由 pages.json 文件用來對 uni-app 進行全局配置&#xff0c;決定頁面文件的路徑、窗口樣式、原生的導航欄、底部的原生tabbar 等。 導航欄高度為 44px (不含狀態欄)&#xff0c;tabBar 高度為 50px (不含安全區)。 它類似微信小程序中app.json的頁面管理部…

SQL思路解析:窗口滑動的應用

目錄 &#x1f3af; 問題目標 第一步&#xff1a;從數據中我們能直接得到什么&#xff1f; 第二步&#xff1a;我們想要的“7天窗口”長什么樣&#xff1f; 第三步&#xff1a;SQL 怎么表達“某一天的前六天”&#xff1f; &#x1f50d;JOIN 比窗口函數更靈活 第四步&am…

解決MyBatis參數綁定中參數名不一致導致的錯誤問題

前言 作為一名Java開發者&#xff0c;我在實際項目中曾多次遇到MyBatis參數綁定的問題。其中最常見的一種情況是&#xff1a;在Mapper接口中定義的參數名與XML映射文件中的占位符名稱不一致&#xff0c;導致運行時拋出Parameter xxx not found類異常。這類問題看似簡單&#x…

黑馬程序員TypeScript課程筆記—類型兼容性篇

類型兼容性的說明 因為傳入的時候只有一個參數 對象之間的類型兼容性 接口之間的類型兼容性 函數之間的類型兼容性&#xff08;函數參數個數&#xff09; 和對象的兼容性正好相反 函數之間的類型兼容性&#xff08;函數參數類型&#xff09; 函數參數的兼容性就不要從接口角度…

智能電視的操作系統可能具備哪些優勢

豐富的應用資源&#xff1a; 操作系統內置了應用商店&#xff0c;提供了豐富的應用資源&#xff0c;涵蓋視頻、游戲、教育等多個領域&#xff0c;滿足不同用戶的多樣化需求。用戶可以輕松下載并安裝所需的應用&#xff0c;享受更多元化的娛樂和學習體驗。 流暢的操作體驗&…

Xget 正式發布:您的高性能、安全下載加速工具!

您可以通過 star 我固定的 GitHub 存儲庫來支持我&#xff0c;謝謝&#xff01;以下是我的一些 GitHub 存儲庫&#xff0c;很有可能對您有用&#xff1a; tzst Xget Prompt Library 原文 URL&#xff1a;https://blog.xi-xu.me/2025/06/02/xget-launch-high-performance-sec…

精美的軟件下載頁面HTML源碼:現代UI與動畫效果的完美結合

精美的軟件下載頁面HTML源碼&#xff1a;現代UI與動畫效果的完美結合 在數字化產品推廣中&#xff0c;一個設計精良的下載頁面不僅能提升品牌專業度&#xff0c;還能顯著提高用戶轉化率。本文介紹的精美軟件下載頁面HTML源碼&#xff0c;通過現代化UI設計與豐富的動畫效果&…

麒麟v10+信創x86處理器離線搭建k8s集群完整過程

前言 最近為某客戶搭建內網的信創環境下的x8s集群&#xff0c;走了一些彎路&#xff0c;客戶提供的環境完全與互聯網分離&#xff0c;通過yum、apt這些直接拉依賴就別想了&#xff0c;用的操作系統和cpu都是國產版本&#xff0c;好在仍然是x86的&#xff0c;不是其他架構&…

Pycharm的使用技巧總結

目錄 一、高效便捷的快捷鍵 二、界面漢化處理 1.設置 2.插件 3.漢化插件安裝 三、修改字體大小、顏色 1.選擇文件-設置 2.選擇編輯器-配色方案-python 3.修改注釋行顏色 4.修改編輯器字體顏色 一、高效便捷的快捷鍵 序號快捷鍵功能場景效果1Ctrl /快速注釋/取消注釋…

安全編碼規范與標準:對比與分析及應用案例

在軟件開發領域&#xff0c;尤其是涉及安全關鍵系統的開發中&#xff0c;遵循編碼規范和標準是確保軟件質量和安全性的重要手段。除了CERT C、CERT Java和MISRA外&#xff0c;還有其他多個與安全相關的編碼規范和標準&#xff0c;以下是一些主要標準的對比說明&#xff1a; 一…

FFmpeg學習筆記

1. 播放器的架構 2. 播放器的渲染流程 3. ffmpeg下載與安裝 3.0 查看PC是否已經安裝了ffmpeg ffmpeg 3.1 下載 wget https://ffmpeg.org/releases/ffmpeg-7.0.tar.gz 3.2 解壓 tar zxvf ffmpeg-7.0.tar.gz && cd ./ffmpeg-7.0 3.3 查看配置文件 ./configure …

大寬帶怎么做

我有10個G的寬帶資源&#xff0c;怎樣運行P2P才能將收益巨大化&#xff0c;主要有以下幾種方式&#xff1a; 1.多設備匯聚模式&#xff1a;使用多臺支持千兆網絡的服務器或專用PCDN設備&#xff08;如N1盒子&#xff09;&#xff0c;將10條寬帶分別接入不同設備&#xff0c;通過…

pytorch基本運算-導數和f-string

引言 在前序對機器學習的探究過程中&#xff0c;我們已經深刻體會到人工智能到處都有微分求導運算&#xff0c;相關文章鏈接包括且不限于&#xff1a; BP神經網絡 邏輯回歸 對于pytorch張量&#xff0c;求導運算必不可少&#xff0c;所以本次就專門來學習一下。 f-string的用…