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. 祖玛游戏相关推荐

  1. 力扣解题思路:脑筋急转弯系列

    172. 阶乘后的零 思路:给定一个整数 n,返回 n! 结果尾数中零的数量. 我们知道,尾部的 0 由 2 * 5 得来,2 的数量明显多于 5 的数量,因为2永远先于5出现,因此只要统计有多少个 ...

  2. 力扣解题思路:位运算系列

    交换两个整数 思路:给定a,b用位运算交换两个数的值: a = a ^ b; b = a ^ b;//b = a ^ b ^ b (这里a,b是初始a,b) a = a ^ b;//a = a ^ b ...

  3. 力扣解题思路:670. 最大交换/parseInt和valueOf的区别

    670. 最大交换 思路: 看到这题我第一反应就是想到下一个排列,不过很快发现这两题并没办法使用同一种思路,因为这一题是要求最大,且只能交换一次,相当于多了很多别的限制. 初步的思路是,直接将数组排序 ...

  4. 力扣解题思路:java 解数独

    37. 解数独 思路:编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个 ...

  5. LeetCode 力扣每日一题 488.祖玛游戏

    题目描述: 你正在参与祖玛游戏的一个变种. 在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 'R'.黄色 'Y'.蓝色 'B'.绿色 'G' 或白色 'W' .你的手中也有一些彩 ...

  6. Java实现 LeetCode 488 祖玛游戏

    488. 祖玛游戏 回忆一下祖玛游戏.现在桌上有一串球,颜色有红色®,黄色(Y),蓝色(B),绿色(G),还有白色(W). 现在你手里也有几个球. 每一次,你可以从手里的球选一个,然后把这个球插入到一 ...

  7. LeetCode每日一题488. 祖玛游戏

    488. 祖玛游戏 你正在参与祖玛游戏的一个变种. 在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 'R'.黄色 'Y'.蓝色 'B'.绿色 'G' 或白色 'W' .你的手中也 ...

  8. 力扣题解: 55. 跳跃游戏

    题目 给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 . 数组中的每个元素代表你在该位置可以跳跃的最大长度. 判断你是否能够到达最后一个下标. 示例 1: 输入:nums = [2,3 ...

  9. 力扣题解:45. 跳跃游戏 II

    题目 给你一个非负整数数组 nums ,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 假设你总是可以到达数组的 ...

最新文章

  1. C/C++ 取整函数 ceil()、floor()、trunc()
  2. 自定义控件添加自定义属性问题
  3. 音视频技术:视频质量评价方法简介 1
  4. 2021-03-09 Matlab RBF神经网络及其实例
  5. 业界首发|阿里云重磅发布云原生架构白皮书
  6. 【pmcaff】2014互联网公司薪资排行榜
  7. c语言课程设计 性别,【图片】发几个C语言课程设计源代码(恭喜自己当上技术小吧主)【东华理工大学吧】_百度贴吧...
  8. C语言图形库——EasyX常用函数
  9. php网页登录制作,thinkphp5 系统登录的实现
  10. 带动量的随机梯度下降法_梯度下降法(SGD)原理解析及其改进优化算法
  11. java判断今天是否是节假日_java 判断日期是否是节假日
  12. 提到单片机很多人都很觉得不陌生,大街小巷上面电子产品都用到
  13. 一份热乎乎的字节面试真题
  14. java spider爬虫_一个简单的java网络爬虫(spider)
  15. (光滑样条)Smoothing spline的数学推导
  16. 淘宝首页交互5--选项卡
  17. win10 桌面颜色变成灰色
  18. Java的socket连接以及string字符串长度过长解决
  19. [pytorch]yolov3.cfg参数详解(每层输出及route、yolo、shortcut层详解)
  20. 向内看 —— Stay hungry.Stay foolish

热门文章

  1. Vbs中sendKeys
  2. 如何更改win7系统里面的文件夹背景色为保护色
  3. “我会对你负责的。”
  4. 水深6到9米有鱼吗_我国四大家鱼之一,营养价值高,为何很少有人养殖?|青鱼|养殖|草鱼|罗非鱼|淡水鱼|黑鱼...
  5. 十年沉浮,Web2 到 Web3 的转变之路
  6. 动画云创始人胥克谦amp;课程格子创始人李天放分享创业经历
  7. 网秦手机杀毒软件 v2.1 symbian uiq 是什么
  8. 如何利用自动化设备行业ERP系统做好材料采购管理
  9. 思想者:漫谈大学生的四个LEARN
  10. 【Python】第二章 内置数据类型