【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練習-中等卷LeetCode
- 【leetcode】19. 刪除連結串列的倒數第N個節點(remove-nth-node-from-end-of-list)(雙指標)[中等]LeetCodeREM指標
- JAVA-LeetCode中等29兩數相除JavaLeetCode
- chrome – 收藏集 – 掘金Chrome
- LeetCode-5426、重新規劃路線-中等LeetCode
- LeetCode C++ 50. Pow(x, n)【Recursion】中等LeetCodeC++
- Android – 收藏集 – 掘金Android
- vue(1) – 收藏集 – 掘金Vue
- JS框架 – 收藏集 – 掘金JS框架
- vue(4) – 收藏集 – 掘金Vue
- iOS面試 – 收藏集 – 掘金iOS面試
- iOS文章 – 收藏集 – 掘金iOS
- 網站 - 收藏集 - 掘金網站
- 【LeetCode刷題(中等程度)】946. 驗證棧序列LeetCode
- node.js – 收藏集 – 掘金Node.js
- java基礎 - 收藏集 - 掘金Java
- 前端面試 - 收藏集 - 掘金前端面試
- 微信&小程式 – 收藏集 – 掘金
- 資料庫 – 收藏集 – 掘金資料庫
- 前端經驗 – 收藏集 – 掘金前端
- iOS必讀 – 收藏集 – 掘金iOS
- iOS知識 – 收藏集 – 掘金iOS
- Leetcode(Python3) 19. Remove Nth Node From End of ListLeetCodePythonREM
- LeetCode C++ 56. Merge Intervals【排序/陣列】中等LeetCodeC++排序陣列
- LeetCode: 1052. 愛生氣的書店老闆(中等)LeetCode
- leetcode:面試題 01.08. 零矩陣(陣列,中等)LeetCode面試題矩陣陣列
- LeetCode C++ 33. Search in Rotated Sorted Array【二分】中等LeetCodeC++
- [LeetCode 中等 動態規劃 ]221. 最大正方形LeetCode動態規劃
- 網路與安全 – 收藏集 – 掘金
- linux運維 – 收藏集 – 掘金Linux運維
- MySQL入門教程 – 收藏集 – 掘金MySql
- 資料庫收集 - 收藏集 - 掘金資料庫
- 資料庫收集 – 收藏集 – 掘金資料庫
- 前端知識大全 - 收藏集 - 掘金前端
- CSS 研究所 - 收藏集 - 掘金CSS