力扣解题思路:488. 祖玛游戏
488. 祖玛游戏
思路:
实际上就是简单的消消乐,如果时间允许,最简单的暴力递归法也是可以的,就是把所有字母插入所有的位置,取最短且可以消去的插入球数即可。但是这样无脑插入是很浪费时间的,所以我们在插入的时候应该先选好合适的位置,分一下两种情况:
(1)插入一个或两个颜色相同的球引发连锁反响。
(2)往两个颜色相同的球中间插入一个颜色不同的球(为什么要这么做呢?见特殊测试用例二)。
注意两个特殊的测试用例:
测试用例一:
"WWRRGGRRWWRRGGRRWW", "GG"
无论怎么插入,都无法完全消除,结果应是-1。测试用例二:
"RRWWRRBBRR", "WB"
"R(B)RWWRRBBRR" -> "R(B)RWW(W)RRBBRR" -> ""
结果应是2。
首先我们需要一个方法来用于消去字符串,返回消去后的结果:
private StringBuilder eliminate(StringBuilder sb) {boolean flag = true;while (flag) {flag = false;for (int i = 0; i < sb.length(); i++) {int j = i + 1;while (j < sb.length() && sb.charAt(j) == sb.charAt(i)) {j++;}if (j - i >= 3) {sb.delete(i, j);flag = true;}}}return sb;}
我们使用Map来保存可用字符的数量,用数组或者hashMap都可以,这里为了简洁我们使用数组:
private int result = Integer.MAX_VALUE;private int[] map = new int[26];private char[] colors = {'R', 'Y', 'B', 'G', 'W'};public int findMinStep(String board, String hand) {for (int i = 0; i < hand.length(); i++) {map[hand.charAt(i) - 'A']++;}dfs(new StringBuilder(board), 0);return result == Integer.MAX_VALUE ? -1 : result;}
接下来就是递归方法的编写,我们先定义递归的出口:
1.到达递归终点(目标字符串已被全部消除)
2.目前已用的字符个数比之前result中的更大(因此不必继续递归)
if (step >= result) return;if (board.length() == 0) {result = Math.min(step, result);return;}
接下来就可以分情况讨论:
(1)插入一个或两个颜色相同的球引发连锁反响。
(2)往两个颜色相同的球中间插入一个颜色不同的球。
for (int i = 0; i < board.length(); i++) {char c = board.charAt(i);int j = i;while (j + 1 < board.length() && board.charAt(j + 1) == c) {j++;}//统计同色球个数if (j == i && map[c - 'A'] >= 2) { //只有单个球StringBuilder tmp = new StringBuilder(board);tmp.insert(i, c + "" + c);map[c - 'A'] -= 2;dfs(eliminate(tmp), step + 2);map[c - 'A'] += 2;} else if (j == i + 1) { //存在两个颜色相同且相邻的球if (map[c - 'A'] >= 1) {StringBuilder tmp = new StringBuilder(board);tmp.insert(i, c);map[c - 'A']--;dfs(eliminate(tmp), step + 1);map[c - 'A']++;}for (char color : colors) {if (color == c) {continue;}if (map[color - 'A'] >= 1) {StringBuilder tmp = new StringBuilder(board);tmp.insert(i + 1, color); //尝试往这两个颜色相同且相邻的球中间插入一个颜色不同的球map[color - 'A']--;dfs(eliminate(tmp), step + 1);map[color - 'A']++;}}}
完整代码如下:
private int result = Integer.MAX_VALUE;private int[] map = new int[26];private char[] colors = {'R', 'Y', 'B', 'G', 'W'};public int findMinStep(String board, String hand) {for (int i = 0; i < hand.length(); i++) {map[hand.charAt(i) - 'A']++;}dfs(new StringBuilder(board), 0);return result == Integer.MAX_VALUE ? -1 : result;}private void dfs(StringBuilder board, int step) {if (step >= result) return;if (board.length() == 0) {result = Math.min(step, result);return;}for (int i = 0; i < board.length(); i++) {char c = board.charAt(i);int j = i;while (j + 1 < board.length() && board.charAt(j + 1) == c) {j++;}if (j == i && map[c - 'A'] >= 2) { //只有单个球StringBuilder tmp = new StringBuilder(board);tmp.insert(i, c + "" + c);map[c - 'A'] -= 2;dfs(eliminate(tmp), step + 2);map[c - 'A'] += 2;} else if (j == i + 1) { //存在两个颜色相同且相邻的球if (map[c - 'A'] >= 1) {StringBuilder tmp = new StringBuilder(board);tmp.insert(i, c);map[c - 'A']--;dfs(eliminate(tmp), step + 1);map[c - 'A']++;}for (char color : colors) {if (color == c) {continue;}if (map[color - 'A'] >= 1) {StringBuilder tmp = new StringBuilder(board);tmp.insert(i + 1, color); //尝试往这两个颜色相同且相邻的球中间插入一个颜色不同的球map[color - 'A']--;dfs(eliminate(tmp), step + 1);map[color - 'A']++;}}}}}private StringBuilder eliminate(StringBuilder sb) {boolean flag = true;while (flag) {flag = false;for (int i = 0; i < sb.length(); i++) {int j = i + 1;while (j < sb.length() && sb.charAt(j) == sb.charAt(i)) {j++;}if (j - i >= 3) {sb.delete(i, j);flag = true;}}}return sb;}
力扣解题思路:488. 祖玛游戏相关推荐
- 力扣解题思路:脑筋急转弯系列
172. 阶乘后的零 思路:给定一个整数 n,返回 n! 结果尾数中零的数量. 我们知道,尾部的 0 由 2 * 5 得来,2 的数量明显多于 5 的数量,因为2永远先于5出现,因此只要统计有多少个 ...
- 力扣解题思路:位运算系列
交换两个整数 思路:给定a,b用位运算交换两个数的值: a = a ^ b; b = a ^ b;//b = a ^ b ^ b (这里a,b是初始a,b) a = a ^ b;//a = a ^ b ...
- 力扣解题思路:670. 最大交换/parseInt和valueOf的区别
670. 最大交换 思路: 看到这题我第一反应就是想到下一个排列,不过很快发现这两题并没办法使用同一种思路,因为这一题是要求最大,且只能交换一次,相当于多了很多别的限制. 初步的思路是,直接将数组排序 ...
- 力扣解题思路:java 解数独
37. 解数独 思路:编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个 ...
- LeetCode 力扣每日一题 488.祖玛游戏
题目描述: 你正在参与祖玛游戏的一个变种. 在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 'R'.黄色 'Y'.蓝色 'B'.绿色 'G' 或白色 'W' .你的手中也有一些彩 ...
- Java实现 LeetCode 488 祖玛游戏
488. 祖玛游戏 回忆一下祖玛游戏.现在桌上有一串球,颜色有红色®,黄色(Y),蓝色(B),绿色(G),还有白色(W). 现在你手里也有几个球. 每一次,你可以从手里的球选一个,然后把这个球插入到一 ...
- LeetCode每日一题488. 祖玛游戏
488. 祖玛游戏 你正在参与祖玛游戏的一个变种. 在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 'R'.黄色 'Y'.蓝色 'B'.绿色 'G' 或白色 'W' .你的手中也 ...
- 力扣题解: 55. 跳跃游戏
题目 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 . 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个下标. 示例 1: 输入:nums = [2,3 ...
- 力扣题解:45. 跳跃游戏 II
题目 给你一个非负整数数组 nums ,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 假设你总是可以到达数组的 ...
最新文章
- C/C++ 取整函数 ceil()、floor()、trunc()
- 自定义控件添加自定义属性问题
- 音视频技术:视频质量评价方法简介 1
- 2021-03-09 Matlab RBF神经网络及其实例
- 业界首发|阿里云重磅发布云原生架构白皮书
- 【pmcaff】2014互联网公司薪资排行榜
- c语言课程设计 性别,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...
- C语言图形库——EasyX常用函数
- php网页登录制作,thinkphp5 系统登录的实现
- 带动量的随机梯度下降法_梯度下降法(SGD)原理解析及其改进优化算法
- java判断今天是否是节假日_java 判断日期是否是节假日
- 提到单片机很多人都很觉得不陌生,大街小巷上面电子产品都用到
- 一份热乎乎的字节面试真题
- java spider爬虫_一个简单的java网络爬虫(spider)
- (光滑样条)Smoothing spline的数学推导
- 淘宝首页交互5--选项卡
- win10 桌面颜色变成灰色
- Java的socket连接以及string字符串长度过长解决
- [pytorch]yolov3.cfg参数详解(每层输出及route、yolo、shortcut层详解)
- 向内看 —— Stay hungry.Stay foolish
热门文章
- Vbs中sendKeys
- 如何更改win7系统里面的文件夹背景色为保护色
- “我会对你负责的。”
- 水深6到9米有鱼吗_我国四大家鱼之一,营养价值高,为何很少有人养殖?|青鱼|养殖|草鱼|罗非鱼|淡水鱼|黑鱼...
- 十年沉浮,Web2 到 Web3 的转变之路
- 动画云创始人胥克谦amp;课程格子创始人李天放分享创业经历
- 网秦手机杀毒软件 v2.1 symbian uiq 是什么
- 如何利用自动化设备行业ERP系统做好材料采购管理
- 思想者:漫谈大学生的四个LEARN
- 【Python】第二章 内置数据类型