【leetcode】LCP 19. 秋葉收藏集(UlBDOe)(DP)[中等]
連結
https://leetcode-cn.com/problems/UlBDOe/
耗時
解題:3 h 15 min
題解:58 min
題意
小扣出去秋遊,途中收集了一些紅葉和黃葉,他利用這些葉子初步整理了一份秋葉收藏集 leaves, 字串 leaves 僅包含小寫字元 r 和 y, 其中字元 r 表示一片紅葉,字元 y 表示一片黃葉。
出於美觀整齊的考慮,小扣想要將收藏集中樹葉的排列調整成「紅、黃、紅」三部分。每部分樹葉數量可以不相等,但均需大於等於 1。每次調整操作,小扣可以將一片紅葉替換成黃葉或者將一片黃葉替換成紅葉。請問小扣最少需要多少次調整操作才能將秋葉收藏集調整完畢。
思路
這是之前 leetcode 一個 CUP 的題,比賽時沒做出來,當時想用貪心,後來看答案才想 DP。由於之前看過答案,自己也沒有思路,所以這是照答案的思路寫的。
三個一維 dp,
dp[0][:] 是字串的字元的排列調整成「紅」一部分,即都換成 r 需要調整多少次;
dp[1][:] 是字串的字元的排列調整成「紅、黃」二部分,即換成 rrrr…yyy 最少需要調整多少次;
dp[2][:] 是字串的字元的排列調整成「紅、黃、紅」三部分,即換成 rrrrr…yyy…rrrr 最少需要調整多少次;
dp[0][i] 非常簡單,直接看 leaves[i] 是不是 r 就行了;
dp[1][i] 就有兩種情況了,…,兩種情況取最小
1. 從 dp[0][i-1] 全是 r 的轉移過來,變成 rrrr...rrrry
2. 從 上一個狀態 dp[1][i-1] 轉移過來,變成 rrrr...rrrry..y
dp[2][i] 和 dp[1][i] 差不多,
1. 從 dp[1][i-1] 轉移過來,變成 rrrr...rrrry..yr
2. 從 上一個狀態 dp[2][i-1] 轉移過來,變成 rrrr...rrrryyyy...yyyyr..r
狀態轉移方程:
{
d
p
[
0
]
[
i
]
=
d
p
[
0
]
[
i
−
1
]
+
1
l
e
a
v
e
s
[
i
]
=
=
′
r
′
d
p
[
1
]
[
i
]
=
m
i
n
(
d
p
[
0
]
[
i
−
1
]
,
d
p
[
1
]
[
i
−
1
]
)
+
1
l
e
a
v
e
s
[
i
]
=
=
′
y
′
d
p
[
2
]
[
i
]
=
m
i
n
(
d
p
[
1
]
[
i
−
1
]
,
d
p
[
2
]
[
i
−
1
]
)
+
1
l
e
a
v
e
s
[
i
]
=
=
′
r
′
\begin{cases} dp[0][i] = dp[0][i-1] + 1^{leaves[i]=='r'} \\ dp[1][i] = min(dp[0][i-1], dp[1][i-1]) + 1^{leaves[i]=='y'} \\ dp[2][i] = min(dp[1][i-1], dp[2][i-1]) + 1^{leaves[i]=='r'} \end{cases}
⎩⎪⎨⎪⎧dp[0][i]=dp[0][i−1]+1leaves[i]==′r′dp[1][i]=min(dp[0][i−1],dp[1][i−1])+1leaves[i]==′y′dp[2][i]=min(dp[1][i−1],dp[2][i−1])+1leaves[i]==′r′
時間複雜度: O ( n ) O(n) O(n)
AC程式碼
class Solution {
public:
int minimumOperations(string leaves) {
int n = leaves.size();
vector<vector<int>> dp(3, vector<int>(n+1, 0));
dp[0][1] = dp[2][1] = dp[1][1] = (leaves[0]=='r'?0:1);
dp[2][2] = dp[1][2] = dp[1][1] + (leaves[1]=='y'?0:1);
dp[0][2] = dp[0][1] + (leaves[1]=='r'?0:1);
for(int i = 3; i <= n; ++i) {
dp[0][i] = dp[0][i-1] + (leaves[i-1]=='r'?0:1);
dp[1][i] = min(dp[0][i-1], dp[1][i-1]) + (leaves[i-1]=='y'?0:1);
dp[2][i] = min(dp[1][i-1], dp[2][i-1]) + (leaves[i-1]=='r'?0:1);
}
return dp[2][n];
}
};
相關文章
- LeetCode 秋葉收藏集LeetCode
- 演算法之DP——秋葉收藏集演算法
- js解leetcode(32)-中等JSLeetCode
- 一 葉 知 秋
- 【leetcode】19. 刪除連結串列的倒數第N個節點(remove-nth-node-from-end-of-list)(雙指標)[中等]LeetCodeREM指標
- JAVA-LeetCode中等29兩數相除JavaLeetCode
- LeetCode-5426、重新規劃路線-中等LeetCode
- 哪些茶葉值得收藏?
- 《和秋葉一起學 PPT》
- LeetCode C++ 376. Wiggle Subsequence【Dynamic Programming】中等LeetCodeC++
- LeetCode C++ 50. Pow(x, n)【Recursion】中等LeetCodeC++
- Leetcode(Python3) 19. Remove Nth Node From End of ListLeetCodePythonREM
- LeetCode C++ 56. Merge Intervals【排序/陣列】中等LeetCodeC++排序陣列
- 【LeetCode刷題(中等程度)】946. 驗證棧序列LeetCode
- 2024.10.2 總結(集訓;DP)
- [LeetCode 中等 動態規劃 ]221. 最大正方形LeetCode動態規劃
- LeetCode: 1052. 愛生氣的書店老闆(中等)LeetCode
- leetcode:面試題 01.08. 零矩陣(陣列,中等)LeetCode面試題矩陣陣列
- LeetCode C++ 316. Remove Duplicate Letters【Stack/Greedy/String】中等LeetCodeC++REM
- LeetCode C++ 1302. Deepest Leaves Sum【Tree/BFS/DFS】中等LeetCodeC++
- 2024.8.31 總結(集訓 考 DP)
- 2024.8.30 總結(集訓 考 DP)
- PK日韓!《非人學園》登上秋葉原大屏
- LeetCode C++ 33. Search in Rotated Sorted Array【二分】中等LeetCodeC++
- node.js – 收藏集 – 掘金Node.js
- 【LeetCode刷題(中等程度)】662. 二叉樹最大寬度LeetCode二叉樹
- [leetcode] 並查集(Ⅱ)LeetCode並查集
- [leetcode] 並查集(Ⅲ)LeetCode並查集
- [leetcode] 並查集(Ⅰ)LeetCode並查集
- 哪些茶葉值得收藏?志強茶超市
- 哪些茶葉值得收藏?志強茶業
- 哪些茶葉值得收藏?志強茶莊
- 網路與安全 – 收藏集 – 掘金
- 資料結構與演算法 | Leetcode 19. Remove Nth Node From End of List資料結構演算法LeetCodeREM
- LeetCode 55. 跳躍遊戲 ( 回溯 dp 貪心LeetCode遊戲
- LeetCode-404-左葉子之和LeetCode
- 【Leetcode 346/700】79. 單詞搜尋 【中等】【回溯深度搜尋JavaScript版】LeetCodeJavaScript
- LeetCode C++ 劍指 Offer 64. 求1+2+…+n【Bit Manipulation】中等LeetCodeC++