488. Zuma Game

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:

  1. You may assume that the initial row of balls on the table won’t have any 3 or more consecutive balls with the same color.
  2. The number of balls on the table won't exceed 20, and the string represents these balls is called "board" in the input.
  3. The number of balls in your hand won't exceed 5, and the string represents these balls is called "hand" in the input.
  4. Both input strings will be non-empty and only contain characters 'R','Y','B','G','W'.

这题主要思路就是深度优先搜索。代码看起来很长,其实思路很简单,大部分代码是用来构造数据结构。 shand手上各个字母的

数目,比如shand="12000",表示手上还有1个R两个Y,vector<multiset<pair<int,int>, greater<pair<int, int>>>> m用来存储各个位置

字母分别在哪些位置出现,并且连续有多少个。比如RRYYWW,经过hash变成001144,则m[0] 就会insert一个{0,2},m[1]会insert一个{2,2},m[4] 会insert一个{4,2};pair<int,int>第一个表示下标,第二个表示个数。

代码如下,经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<multiset<pair<int,int>, greater<pair<int, int>>>> m(5, multiset<pair<int, int>, greater<pair<int, int>>>());
		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<pair<int, int>, greater<pair<int, int>>>& sev = m[i];
			for (const pair<int, int>& 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;
	}
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章