【leetcode解題日記】134. 加油站 (中等)

更新於 發佈於 閱讀時間約 4 分鐘

今天來分享一個中等難度的 LeetCode 題目 —— 加油站問題(Gas Station)。看到這道題的第一直覺是透過窮舉法來測試所有的起點,但也可以透過線性時間解法來優雅的解決這個問題。

題目說明

在一條環形公路上有 n 個加油站,第 i 個加油站有汽油 gas[i] 升。你的車油箱容量無限,從第 i 個加油站開往第 i+1 個加油站需要消耗汽油 cost[i] 升。你從某個加油站出發(初始油箱為空),給定兩個整數陣列 gas 和 cost,如果能環繞一周回到起點,則返回出發的加油站編號,否則返回 -1。如果存在解,則 保證 它是 唯一 的。

解題思路

這道題有個重要前提:如果有解,則解是唯一的。利用這點,我們可以設計一個 O(n) 的算法:

var canCompleteCircuit = function(gas, cost) {

let balance = 0; // 如果總油量大於總消耗,則可以跑完全程
let minIndex = 0, minBalance = 0; // 紀錄最小餘額(初始設為0,因為我們假設從索引0開始時的起始餘額為0)以及最小餘額出現後的下一個加油站
for(let i = 0; i < gas.length; i++){
balance += gas[i] - cost[i]; // 計算每站的油量變化
if(balance < minBalance){ // 如果油量餘額小於 0,則可以得知此處為最小餘額的位置
minBalance = balance; // 找到新的最小餘額點
minIndex = i + 1 // 紀錄最小餘額出現後的下一個加油站為可能起始點
}
}
return balance >= 0 ? minIndex : -1
};


關鍵變數

  • balance
    • 用途:記錄從起點開始到當前位置的累計油量餘額
    • 計算方式:每站獲得的油量(gas[i])減去前往下一站消耗的油量(cost[i])
    • 意義:表示車子在行駛過程中的「油箱餘額」,正值表示有多餘的油,負值表示油不夠
  • minBalance
    • 用途:記錄整個循環過程中遇到的最小餘額
    • 初始值設為0是因為我們假設從0位置開始,初始餘額為0
    • 意義:幫助找出最佳起點,因為最小餘額之後的位置可能是更好的起點
  • minIndex
    • 用途:記錄最小餘額出現後的下一個位置
    • 當找到新的最小餘額時會更新為當前位置+1
    • 意義:這就是解決問題的關鍵 - 它標記了可能的最佳起點

總結

透過從油量最少的索引0的位置開始行駛,如果在某個加油站(balance)的油量變為負數,則可以確定由0出發不可行。由於環形路線的特性,如果總油量大於總消耗(balance > 0),則必然存在一個起點可以完成環繞。

最小餘額點之後的位置是最佳起點,因為:

  • 從這點出發,我們會先經過油量最充裕的部分
  • 到達最小餘額點時,已經確保有足夠的油量才通過這個困難點

​相較於窮舉法,此解法可以將時間複雜度從 O(n²) 降至 O(n)。



留言
avatar-img
留言分享你的想法!
紫-avatar-img
2025/05/06
很有幫助~!剛好想了解
avatar-img
dizzydog的沙龍
1會員
5內容數
親愛的訪客您好!我是 dizzydog,一位熱衷於前端技術的工程師。這個部落格是我的數位筆記本,記錄著我在程式開發路上的各種發現、挑戰與突破。我相信「輸出」是最有效的學習方式,透過清晰地表達所學,不僅能加深自己的理解,也能幫助其他走在相同道路上的開發者。 歡迎您在這裡探索以及交流。
你可能也想看
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
創作者營運專員/經理(Operations Specialist/Manager)將負責對平台成長及收入至關重要的 Partnership 夥伴創作者開發及營運。你將發揮對知識與內容變現、影響力變現的精準判斷力,找到你心中的潛力新星或有聲量的中大型創作者加入 vocus。
Thumbnail
LeetCode 是一個程式語言版的線上題庫平臺,提供題目描述、程式碼區塊、解題者分享的解法和疑問討論。藉由這篇文章分享我在 LeetCode 上的使用經驗和觀點,包括刷題的重要性、解題心態和練習目標。
Thumbnail
LeetCode 是一個程式語言版的線上題庫平臺,提供題目描述、程式碼區塊、解題者分享的解法和疑問討論。藉由這篇文章分享我在 LeetCode 上的使用經驗和觀點,包括刷題的重要性、解題心態和練習目標。
Thumbnail
題目敘述 Solving Questions With Brainpower 給定一個測驗題陣列,每個欄位都是一個pair, 分別記錄測驗題做完可以得到的分數,和需要的冷卻時間 (也就是會有一段時間不能作答接下來的題目)。 請問在最佳的答題策略下,最多可以獲得多少分數?
Thumbnail
題目敘述 Solving Questions With Brainpower 給定一個測驗題陣列,每個欄位都是一個pair, 分別記錄測驗題做完可以得到的分數,和需要的冷卻時間 (也就是會有一段時間不能作答接下來的題目)。 請問在最佳的答題策略下,最多可以獲得多少分數?
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定一個輸入字串s和一套編碼規則,要求我們針對字串s進行解碼,並且以字串的形式返回答案。 編碼規則: 數字[字串] -> []內的字串以對應倍數做展開,而且允許巢狀編碼。 例如: 3[a] 解碼完就是 aaa 2[bc] 解碼完就是 bcbc 2[a2[b]] = 2
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
Thumbnail
題目敘述 題目會給定我們兩個輸入字串word1, word2,要求我們依照word1,word2,word1,word2, ... 交叉前進的方式,合併兩個字串,作為輸出。 題目的原文敘述 測試範例 Example 1: Input: word1 = "abc", word2 = "pq
Thumbnail
題目敘述 題目會給定兩個輸入。 第一個輸入是關鍵字清單products,第二個是使用者輸入的字串searchWord。 要求我們實現關鍵字搜尋建議系統,使用者每輸入一個字元就推薦一次。 推薦時,優先返回字典序(Lecial order)最接近的關鍵字,最多不要超過三個關鍵字。 題目的原文
Thumbnail
題目敘述 題目會給定兩個輸入。 第一個輸入是關鍵字清單products,第二個是使用者輸入的字串searchWord。 要求我們實現關鍵字搜尋建議系統,使用者每輸入一個字元就推薦一次。 推薦時,優先返回字典序(Lecial order)最接近的關鍵字,最多不要超過三個關鍵字。 題目的原文
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News