生活随笔
收集整理的這篇文章主要介紹了
LeetCode 1824. 最少侧跳次数(DP)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
文章目錄
1. 題目
給你一個長度為 n 的 3 跑道道路 ,它總共包含 n + 1 個 點 ,編號為 0 到 n 。
一只青蛙從 0 號點第二條跑道 出發(fā) ,它想要跳到點 n 處。然而道路上可能有一些障礙。
給你一個長度為 n + 1 的數(shù)組 obstacles ,其中 obstacles[i] (取值范圍從 0 到 3)表示在點 i 處的 obstacles[i] 跑道上有一個障礙。
如果 obstacles[i] == 0 ,那么點 i 處沒有障礙。
任何一個點的三條跑道中 最多有一個 障礙。
比方說,如果 obstacles[2] == 1 ,那么說明在點 2 處跑道 1 有障礙。
這只青蛙從點 i 跳到點 i + 1 且跑道不變的前提是點 i + 1 的同一跑道上沒有障礙。
為了躲避障礙,這只青蛙也可以在 同一個 點處 側(cè)跳 到 另外一條 跑道(這兩條跑道可以不相鄰),但前提是跳過去的跑道該點處沒有障礙。
比方說,這只青蛙可以從點 3 處的跑道 3 跳到點 3 處的跑道 1 。
這只青蛙從點 0 處跑道 2 出發(fā),并想到達點 n 處的 任一跑道 ,請你返回 最少側(cè)跳次數(shù) 。
注意:點 0 處和點 n 處的任一跑道都不會有障礙。
示例 1:
輸入:obstacles
= [0,1,2,3,0]
輸出:
2
解釋:最優(yōu)方案如上圖箭頭所示。總共有
2 次側(cè)跳(紅色箭頭)。
注意,這只青蛙只有當(dāng)側(cè)跳時才可以跳過障礙(如上圖點
2 處所示)。
示例 2:
輸入:obstacles
= [0,1,1,3,3,0]
輸出:
0
解釋:跑道
2 沒有任何障礙,所以不需要任何側(cè)跳。
示例 3:
輸入:obstacles
= [0,2,1,0,3,0]
輸出:
2
解釋:最優(yōu)方案如上圖所示。總共有
2 次側(cè)跳。提示:
obstacles
.length
== n
+ 1
1 <= n
<= 5 * 10^5
0 <= obstacles
[i
] <= 3
obstacles
[0] == obstacles
[n
] == 0
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/minimum-sideway-jumps
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
2. 解題
- dp[pos][道的編號1-3] 表示到pos位置處在第幾號道上的最少側(cè)跳次數(shù)
class Solution {
public:int minSideJumps(vector
<int>& obstacles
) {int n
= obstacles
.size();vector
<vector
<int>> dp(n
, vector
<int>(4, INT_MAX
));dp
[0][1] = dp
[0][3] = 1;dp
[0][2] = 0;for(int i
= 1; i
< n
; ++i
){int prev
= obstacles
[i
-1];int cur
= obstacles
[i
];for(int j
= 1; j
<= 3; ++j
){if(prev
&& prev
==j
)continue;for(int k
= 1; k
<= 3; ++k
){if(cur
&& cur
==k
)continue;if(j
== k
)dp
[i
][k
] = min(dp
[i
][k
], dp
[i
-1][j
]);else if(prev
==k
&& cur
==j
)dp
[i
][k
] = min(dp
[i
][k
], dp
[i
-1][j
]+2);elsedp
[i
][k
] = min(dp
[i
][k
], dp
[i
-1][j
]+1);}}}return min(dp
[n
-1][1], min(dp
[n
-1][2], dp
[n
-1][3]));}
};
760 ms 267.3 MB C++
- 當(dāng)前狀態(tài)只跟上一狀態(tài)有關(guān),狀態(tài)可以壓縮
class Solution {
public:int minSideJumps(vector
<int>& obstacles
) {int n
= obstacles
.size();vector
<int> dp(4), tmp(4);dp
[1] = dp
[3] = 1;dp
[2] = 0;for(int i
= 1; i
< n
; ++i
){tmp
[1]=tmp
[2]=tmp
[3]=INT_MAX
;int prev
= obstacles
[i
-1];int cur
= obstacles
[i
];for(int j
= 1; j
<= 3; ++j
){if(prev
&& prev
==j
)continue;for(int k
= 1; k
<= 3; ++k
){if(cur
&& cur
==k
)continue;if(j
== k
)tmp
[k
] = min(tmp
[k
], dp
[j
]);else if(prev
==k
&& cur
==j
)tmp
[k
] = min(tmp
[k
], dp
[j
]+2);elsetmp
[k
] = min(tmp
[k
], dp
[j
]+1);}}swap(dp
, tmp
);}return min(dp
[1], min(dp
[2], dp
[3]));}
};
380 ms 158.3 MB C++
我的CSDN博客地址 https://michael.blog.csdn.net/
長按或掃碼關(guān)注我的公眾號(Michael阿明),一起加油、一起學(xué)習(xí)進步!
總結(jié)
以上是生活随笔為你收集整理的LeetCode 1824. 最少侧跳次数(DP)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。