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;
	}
};

 

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