Think about Zuma Game. You have a row of balls on the table, colored red(R), yellow(Y), blue(B), green(G), and white(W). You also have several balls in your hand.
Each time, you may choose a ball in your hand, and insert it into the row (including the leftmost place and rightmost place). Then, if there is a group of 3 or more balls in the same color touching, remove these balls. Keep doing this until no more balls can be removed.
Find the minimal balls you have to insert to remove all the balls on the table. If you cannot remove all the balls, output -1.
Examples:
Input: "WRRBBW", "RB"
Output: -1
Explanation: WRRBBW -> WRR[R]BBW -> WBBW -> WBB[B]W -> WW
Input: "WWRRBBWW", "WRBRW"
Output: 2
Explanation: WWRRBBWW -> WWRR[R]BBWW -> WWBBWW -> WWBB[B]WW -> WWWW -> empty
Input:"G", "GGGGG"
Output: 2
Explanation: G -> G[G] -> GG[G] -> empty
Input: "RBYYBBRRB", "YRBGB"
Output: 3
Explanation: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> RRRB -> B -> B[B] -> BB[B] -> empty
Note:
这题主要思路就是深度优先搜索。代码看起来很长,其实思路很简单,大部分代码是用来构造数据结构。 shand手上各个字母的
数目,比如shand="12000",表示手上还有1个R两个Y,vector
字母分别在哪些位置出现,并且连续有多少个。比如RRYYWW,经过hash变成001144,则m[0] 就会insert一个{0,2},m[1]会insert一个{2,2},m[4] 会insert一个{4,2};pair
代码如下,经leetcode测试,只需0ms beating 100%
class Solution {
public:
int ans = 6;
int findMinStep(string board, string hand) {
if (board.empty()) return 0;
string shand = "00000";
string s = "";
for (char& c : hand)
shand[hash(c)]++;
for(char& c:board)
s += hash(c) + '0';
int ans = dfs(s, shand, 0);
return ans == 6 ? -1 : ans;
}
private:
int dfs(string board, string& shand,int deep) {
if (board.empty()) return 0;
if (deep >= ans||shand=="00000") return 6;
vector, greater>>> m(5, multiset, greater>>());
int i = 0;
for (; i < board.size()-1; ++i) {
if (board[i] == board[i + 1])
m[board[i] - '0'].insert({ 2,i++ });
else
m[board[i] - '0'].insert({ 1,i });
}
if (i != board.size())
m[board[i] - '0'].insert({ 1,i });
int ans = 6;
for (int i = 0; i < 5; i++) {
if (shand[i] == '0') continue;
multiset, greater>>& sev = m[i];
for (const pair& c : sev) {
if (shand[i] < 3 - c.first + '0') break;
shand[i] -= 3 - c.first;
int pre = c.second - 1, post = c.second + c.first, pre1 = pre, post1 = post;
while (pre >= 0 && post < board.size() && board[pre] == board[post]) {
while (pre1 > 0 && board[pre1] == board[pre1 - 1]) pre1--;
while (post1 < board.size() - 1 && board[post1] == board[post1 + 1]) post1++;
if (pre - pre1 + post1 - post > 0) {
pre = --pre1;
post = ++post1;
}
else break;
}
string s = board.substr(0, pre + 1) +(post < board.size() ? board.substr(post) : "");
ans = min(ans, 3 - c.first + dfs(s, shand, deep + 3 - c.first));
shand[i] += 3 - c.first;
}
}
return ans;
}
int hash(char c) {
if (c == 'R') return 0;
if (c == 'Y') return 1;
if (c == 'B') return 2;
if (c == 'G') return 3;
if (c == 'W') return 4;
}
};