貪欲で 輪を 1 周できる 出発点を求める
輪に
海外で定番の問題リスト 4 本には入っていません
問題
輪にi ではcharge[i] だけ足せ、i からcost[i] だけ-1 を
- 1 周できる
出発の 充電所が あるなら、 それは 1 つだけに なるような 入力だけが 渡されます - 進む途中で
電気が ちょうど 0 に なるのは かまいませんが、 負に なる 所へは 進めません - 電池には
上限が なく、 足した 電気は 全部 たまります chargeとcostの長さは 同じで 1 以上 100000 以下、 値は どれも 0 以上 10000 以下です
入力と出力の例
例 1
充電所 2 から
例 2
足せる
例 3
充電所が 1 つだけで、
面接での聞かれ方
面接では、
- 「輪に
なった 道に スタンドが あります。 1 周できる 出発点を 答えてください」 - 最初に
全部の 出発点を 試す 書き方を 話し、 「O(n) に できますか」と 聞かれる 流れが よくあります - 書き終えた
あとに 「なぜ 足りなくなった 所の 次から 出直して よいのですか」と、 理由を 聞かれる こともあります
答えが
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
アルゴリズムのチートシートの「配列と文字列」に、
関わる学び
配列と
まず 考える手順
段 1
素直に
段 2
まず、
段 3
充電所 s からi でs と i のi でi + 1 に
解答
Python
Python
def start_station(charge, cost):
total = 0
tank = 0
start = 0
for i in range(len(charge)):
gain = charge[i] - cost[i]
total += gain
tank += gain
if tank < 0:
start = i + 1
tank = 0
if total < 0:
return -1
return startJavaScript
JavaScript
function startStation(
charge, cost
) {
let total = 0;
let tank = 0;
let start = 0;
const n = charge.length;
for (let i = 0; i < n; i++) {
const gain = charge[i] - cost[i];
total += gain;
tank += gain;
if (tank < 0) {
start = i + 1;
tank = 0;
}
}
return total < 0 ? -1 : start;
}Go
Go
func startStation(
charge, cost []int,
) int {
total, tank, start := 0, 0, 0
for i := range charge {
gain := charge[i] - cost[i]
total += gain
tank += gain
if tank < 0 {
start = i + 1
tank = 0
}
}
if total < 0 {
return -1
}
return start
}合計がstart が n に
計算量
- 時間は O(n) です。
充電所を 前から 1 回なめ、 1 か 所ごとの 手間は一定です - 使う
記憶は O(1) です。 持つのは 合計、 いまの 電気、 候補の 番号の 3 つだけです - 段 1 の
全部の 出発点を 試す 書き方は O(n²) かかります
よく ある間違い
- 合計を
確かめずに 候補を返す。 例 2 では、 前から 見ると 充電所 0 で -1 に なって 候補が 1 へ 移り、 その あとは 0 のまま 負に ならないので、 合計を 見ないと 1 を 返します。 1 周できない ことは 合計でしか 分かりません - 候補を
iにする。 足りなくなった充電所 iから出ても、 iから次へ 進む所で 同じく 足りなくなります。 候補は i + 1です - 電気が 0 に
なったら出直す。 条件を tank <= 0と書くと、 例 3 の 充電所 1 つで 電気が ちょうど 0 に なり、 候補が 1 に 移って 範囲の 外を 返します。 出直すのは 負に なった ときだけです - 輪を 2 周なめて
確かめ直す。 合計が 足りていれば 候補で 必ず 1 周できるので、 2 周目は 要りません。 書いても 答えは 合いますが、 理由を 説明できないと、 面接ではかえって 迷っているように見えます
解答を動かした版 Python 3.14.7Node.js 24.22.1Go 1.24.2確認日 2026年11月8日
面接での 話し方の例
書き始める
「全部の
出発点を 試すと O(n²) です。 まず、 足せる 電気の 合計が 使う 電気の 合計より 少なければ -1 です。 合計が 足りていれば 答えは あるので、 前から 電気を 足し 引きして、 負に なったら その 次の 充電所を 新しい 候補に して 電気を 0 に 戻します。 間の どこから 出ても 同じ所で 足りなくなるので、 飛ばして よいからです。 時間は O(n)、 記憶は O(1) です。」
書き終えたら、
「例 1 の
差は 1、 -3、 4、 -1 で、 合計は 1 なので 答えは あります。 充電所 0 で 電気は 1、 充電所 1 で -2 に なって 負なので、 候補を 2 に して 電気を 0 に 戻します。 充電所 2 で 4、 充電所 3 で 3 と 負にならず、 答えは 2 です。」