iT邦幫忙

2026 iThome 鐵人賽

DAY 26
1
Software Development

快樂演算法系列 第 26

資安課 & E-bike Triathlon bike & 45

  • 分享至 

  • xImage
  •  

1.最少要跳幾次才能到最後一格
2.
nums = [2,3,1,1,4]
index 0 1 2 3 4
一種最佳走法:0 → 1 → 4;答案:2
最速解還是 Greedy(貪婪演算法),Time O(n)、Space O(1)。
currentEnd = 目前這跳涵蓋到哪
jumps = 已跳幾次
3.

class Solution {
public:
    int jump(vector<int>& nums) {//找到終點最少要跳幾次
        int farthest = 0;//目前看過的位置中,最遠到哪
        int currentEnd = 0;//這一跳能到的最遠邊
        int jumps = 0;//已跳幾次

        for (int current = 0; current < nums.size() - 1; ++current) {//不用處理最後一格
            farthest = max(farthest, current + nums[current]);//更新下一跳最遠可以到哪

            if (current == currentEnd) {//已走完目前這一跳的可達範圍
                ++jumps;//下一跳
                currentEnd = farthest;//下一跳的邊界更新成最遠位置
            }
        }

        return jumps;//回傳最少跳躍次數
    }
};

4.nums = [2,3,1,1,4]
開始:currentEnd = 0;farthest = 0;jumps = 0
current = 0
farthest = 0 + 2 = 2

current == currentEnd
0 == 0
→ jumps = 1
→ currentEnd = 2現在代表:第 1 跳可以涵蓋 index 1~2。

繼續看 index 1:1 + nums[1]= 1 + 3= 4;farthest = 4
走到目前邊界 current = 2:jumps = 2;currentEnd = 4已經到終點。

#45:除了最遠位置,再記「這一跳的邊界」;走到邊界就 jumps + 1。

5.0 <= j <= nums[i]不能超過這格允許的最大距離。
i + j < n確保跳完不能飛出陣列外面。
nums = [2,3,1,1,4]
index 0 1 2 3 4
一開始:index 0 的值 = 2可選
跳 1 格 → index 1;跳 2 格 → index 2
index 0→ 跳 1 格→ index 1;到了 index 1:nums[1] = 3最多可以跳 3 格:
index 1→ 跳 3 格→ index 4
=> 0 --跳1格--> 1 --跳3格--> 4;共只跳 2 次

自己選這次實際跳 j 格,目標是用最少次數到最後一格。]

6.題目定義裡有j,但最快解其實根本不用真的決定 j。
站在 index i,最多可以跳 nums[i] 格,j 可以是 1 ~ nums[i]
但最佳 Greedy 不會真的枚舉每個 j,不然很容易變慢。
nums[0]=2→ 可到 index 1、2
不急著決定跳 1 還是 2,而是把這一整段 [1,2] 都看一遍:
index 1 → 1+3=4
index 2 → 2+1=3所以這一跳範圍內,下一跳最遠能到:farthest = 4

第 1 跳:涵蓋到 index 2
第 2 跳:可以涵蓋到 index 4 → 答案 2

最快不是:找 nums[i] 最大的格子。
->在目前這一跳能到的所有位置裡,找「下一跳能把邊界推最遠」的結果。
大於目前次數就不管比較像 BFS 剪枝;這題更漂亮,直接用:
currentEnd = 目前這一跳的邊界
farthest = 下一跳最遠邊界
走到 currentEnd → jumps + 1
不用 O(n²),也不用真的把所有 j 一個個試完。

7.每個位置只被掃一次,不會從每個位置再把所有可跳距離全部重試。

不是:每個位置 × 每種跳法→ O(n²)
而是:每個位置只看一次→ O(n)這就是這題 Greedy 能快的原因。

8.不是選 nums[i] 最大,而是選 i + nums[i] 的最大可達邊界;不會漏掉「先跳近一點、下一格更強」的路,因為下一輪仍會把目前邊界內的每個 index 都掃到。
nums = [2,2,3,10,0,0]
index 0 1 2 3 4 5
第一跳可到 1、2:
index 1 → 1+2 = 3;index 2 → 2+3 = 5;→ farthest = 5
雖然 index 1 只推到 3,但下一輪會掃 3~5,所以還是會看到:
index 3 → 3+10 = 13
因此那條「先近、後面突然跳很遠」的路不會被丟掉。

9.因為 currentEnd 代表「目前這一跳可以涵蓋到哪裡」。
currentEnd = 0;jumps = 0
看 current = 0:
farthest = 0 + 2 = 2
且:current == currentEnd;0 == 0代表「第一跳的範圍看完了」
jumps = 1;currentEnd = 2;接著掃 index 1、2,算出:
index 1 → 1+3 = 4
index 2 → 2+1 = 3;farthest = 4
走到:current = 2;currentEnd = 2表示這一跳的範圍看完了so
jumps = 2;currentEnd = 4而最後 index 就是 4,所以已經能到終點。

走到 currentEnd = 這一跳的可達範圍掃完了,所以 jumps+1,再把下一跳邊界更新成 farthest。


上一篇
線上點餐,每次要點一道菜都要重頭找到尾就是n*n &55v3
下一篇
十幾萬鎊還是不要 -> let's all in third train & 療癒的甜點 &62
系列文
快樂演算法30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
AndyAWD
iT邦研究生 5 級 ‧ 2026-09-14 23:48:25

剩四天啦!

想放假

0
饅頭
iT邦新手 5 級 ‧ 2026-09-15 22:14:37

快結束囉!!

我要留言

立即登入留言