算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !
今天和大家聊的问题叫做 祖玛游戏,我们先来看题面:
https://leetcode-cn.com/problems/zuma-game/
示例 1:
输入:board = "WRRBBW", hand = "RB"
输出:-1
解释:无法移除桌面上的所有球。可以得到的最好局面是:
- 插入一个 'R' ,使桌面变为 WRRRBBW 。WRRRBBW -> WBBW
- 插入一个 'B' ,使桌面变为 WBBBW 。WBBBW -> WW
桌面上还剩着球,没有其他球可以插入。
示例 2:
输入:board = "WWRRBBWW", hand = "WRBRW"
输出:2
解释:要想清空桌面上的球,可以按下述步骤:
- 插入一个 'R' ,使桌面变为 WWRRRBBWW 。WWRRRBBWW -> WWBBWW
- 插入一个 'B' ,使桌面变为 WWBBBWW 。WWBBBWW -> WWWW -> empty
只需从手中出 2 个球就可以清空桌面。
示例 3:
输入:board = "G", hand = "GGGGG"
输出:2
解释:要想清空桌面上的球,可以按下述步骤:
- 插入一个 'G' ,使桌面变为 GG 。
- 插入一个 'G' ,使桌面变为 GGG 。GGG -> empty
只需从手中出 2 个球就可以清空桌面。
示例 4:
输入:board = "RBYYBBRRB", hand = "YRBGB"
输出:3
解释:要想清空桌面上的球,可以按下述步骤:
- 插入一个 'Y' ,使桌面变为 RBYYYBBRRB 。RBYYYBBRRB -> RBBBRRB -> RRRB -> B
- 插入一个 'B' ,使桌面变为 BB 。
- 插入一个 'B' ,使桌面变为 BBB 。BBB -> empty
只需从手中出 3 个球就可以清空桌面。
https://www.acwing.com/solution/leetcode/content/2588/
我们先将手中的球用哈希表来存储一下,然后看桌上的球能否在哈希表里的球添加后消除,然后消除后递归处理剩下的。中间记录需要的球数,用来更新需要球数的最小值。如果最小值超出了手中球的个数,则无法消除。
时间复杂度分析:桌上的球不会超过20个,手中的球不会超过5个,所以时间复杂度为O(m+n).
class Solution {
public:
string del(string board){
for(int i=0;i<board.size();){
int j=i;
while(j<board.size()&&board[i]==board[j])j++;
if(j-i>=3)
return del(board.substr(0,i)+board.substr(j));
else i=j;
}
return board;
}
int dfs(string board, unordered_map<char,int>&hash){
board=del(board);
if(board.size()==0)return 0;
int rs=6,need=0;
for(int i=0;i<board.size();){
int j=i;
while(j<board.size()&&board[i]==board[j])j++;
need=3-(j-i);
if(hash[board[i]]>=need){
hash[board[i]]-=need;
rs=min(rs,need+dfs(board.substr(0,i)+board.substr(j),hash));
hash[board[i]]+=need;
}
i=j;
}
return rs;
}
int findMinStep(string board, string hand) {
unordered_map<char,int>hash;
for(auto x:hand)hash[x]++;
int res=dfs(board,hash);
return res==6?-1:res;
}
};
好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。
上期推文: