488. 祖玛游戏【我亦无他唯手熟尔】
488. 祖玛游戏
难度 困难
你正在参与祖玛游戏的一个变种。
在这个祖玛游戏变体中,桌面上有 一排 彩球,每个球的颜色可能是:红色 'R'
、黄色 'Y'
、蓝色 ‘B’、绿色 'G'
或白色 'W'
。你的手中也有一些彩球。
你的目标是 清空 桌面上所有的球。每一回合:
- 从你手上的彩球中选出 任意一颗 ,然后将其插入桌面上那一排球中:两球之间或这一排球的任一端。
- 接着,如果有出现 三个或者三个以上 且 颜色相同 的球相连的话,就把它们移除掉。
- 如果这种移除操作同样导致出现三个或者三个以上且颜色相同的球相连,则可以继续移除这些球,直到不再满足移除条件。
- 如果桌面上所有球都被移除,则认为你赢得本场游戏。
- 重复这个过程,直到你赢了游戏或者手中没有更多的球。‘
给你一个字符串 board
,表示桌面上最开始的那排球。另给你一个字符串 hand
,表示手里的彩球。请你按上述操作步骤移除掉桌上所有球,计算并返回所需的 最少 球数。如果不能移除桌上所有的球,返回 -1
。
示例 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 个球就可以清空桌面。
提示:
1 <= board.length <= 16
1 <= hand.length <= 5
board
和hand
由字符'R'
、'Y'
、'B'
、'G'
和'W'
组成- 桌面上一开始的球中,不会有三个及三个以上颜色相同且连着的球
题解
官方
广度优先搜索
class Solution:def findMinStep(self, board: str, hand: str) -> int:def clean(s):# 消除桌面上需要消除的球n = 1while n:s, n = re.subn(r"(.)\1{2,}", "", s)return shand = "".join(sorted(hand))# 初始化用队列维护的状态队列:其中的三个元素分别为桌面球状态、手中球状态和回合数queue = deque([(board, hand, 0)])# 初始化用哈希集合维护的已访问过的状态visited = {(board, hand)}while queue:cur_board, cur_hand, step = queue.popleft()for i, j in product(range(len(cur_board) + 1), range(len(cur_hand))):# 第 1 个剪枝条件: 当前球的颜色和上一个球的颜色相同if j > 0 and cur_hand[j] == cur_hand[j - 1]:continue# 第 2 个剪枝条件: 只在连续相同颜色的球的开头位置插入新球if i > 0 and cur_board[i - 1] == cur_hand[j]:continue# 第 3 个剪枝条件: 只在以下两种情况放置新球# - 第 1 种情况 : 当前球颜色与后面的球的颜色相同# - 第 2 种情况 : 当前后颜色相同且与当前颜色不同时候放置球 choose = Falseif 0 < i < len(cur_board) and cur_board[i - 1] == cur_board[i] and cur_board[i - 1] != cur_hand[j]:choose = Trueif i < len(cur_board) and cur_board[i] == cur_hand[j]:choose = Trueif choose:new_board = clean(cur_board[:i] + cur_hand[j] + cur_board[i:])new_hand = cur_hand[:j] + cur_hand[j + 1:]if not new_board:return step + 1if (new_board, new_hand) not in visited:queue.append((new_board, new_hand, step + 1))visited.add((new_board, new_hand))return -1作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/zuma-game/solution/zu-ma-you-xi-by-leetcode-solution-lrp4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
深度优先搜索
import re
from functools import lru_cache
from itertools import productclass Solution:def findMinStep(self, board: str, hand: str) -> int:ans = self.dfs(board, "".join(sorted(hand)))return ans if ans <= 5 else -1@lru_cache(None)def dfs(self, cur_board: str, cur_hand: str):if not cur_board:return 0res = 6for i, j in product(range(len(cur_board) + 1), range(len(cur_hand))):# 第 1 个剪枝条件: 手中颜色相同的球只需要考虑其中一个即可if j > 0 and cur_hand[j] == cur_hand[j - 1]:continue# 第 2 个剪枝条件: 只在连续相同颜色的球的开头位置插入新球if i > 0 and cur_board[i - 1] == cur_hand[j]:continue# 第 3 个剪枝条件: 只考虑放置新球后有可能得到更优解的位置# - 第 1 种情况 : 当前球颜色与后面的球的颜色相同 # - 第 2 种情况 : 当前后颜色相同且与当前颜色不同时候放置球choose = Falseif 0 < i < len(cur_board) and cur_board[i - 1] == cur_board[i] and cur_board[i - 1] != cur_hand[j]:choose = Trueif i < len(cur_board) and cur_board[i] == cur_hand[j]:choose = Trueif choose:new_board = self.clean(cur_board[:i] + cur_hand[j] + cur_board[i:])new_hand = cur_hand[:j] + cur_hand[j + 1:]res = min(res, self.dfs(new_board, new_hand) + 1)return res@staticmethoddef clean(s):n = 1while n:s, n = re.subn(r'(.)\1{2,}', '', s)return s作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/zuma-game/solution/zu-ma-you-xi-by-leetcode-solution-lrp4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
488. 祖玛游戏【我亦无他唯手熟尔】相关推荐
- 237. 删除链表中的节点【我亦无他唯手熟尔】
237. 删除链表中的节点 请编写一个函数,用于 删除单链表中某个特定节点 .在设计函数时需要注意,你无法访问链表的头节点 head ,只能直接访问 要被删除的节点 . 题目数据保证需要删除的节点 不 ...
- 136. 只出现一次的数字【我亦无他唯手熟尔】
136. 只出现一次的数字 136. 只出现一次的数字 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素.说明:你的算法应该具有线性时间复杂度. 你 ...
- 1929. 数组串联【我亦无他唯手熟尔】
1929. 数组串联 题目 题解 题目 给你一个长度为 n 的整数数组 nums .请你构建一个长度为 2n 的答案数组 ans ,数组下标 从 0 开始计数 ,对于所有 0 <= i < ...
- 438. 找到字符串中所有字母异位词【我亦无他唯手熟尔】
438. 找到字符串中所有字母异位词 438. 找到字符串中所有字母异位词 题解 官方 438. 找到字符串中所有字母异位词 难度 中等 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 ...
- 786. 第 K 个最小的素数分数【我亦无他唯手熟尔】
786. 第 K 个最小的素数分数 786. 第 K 个最小的素数分数 题解 786. 第 K 个最小的素数分数 难度 困难 给你一个按递增顺序排序的数组 arr 和一个整数 k .数组 arr 由 ...
- 樊登读书搞定读后感_读书笔记/读后感《读懂一本书,樊登读书法》——无他唯手熟尔...
当我们在生活及工作中遇到问题的时候,通常会请教同事或者上网搜索解决方法,但是我们忽略了另外一个解决问题的途径,那就是通过阅读书籍积累知识.为什么大家并不习惯于阅读书籍呢,那是因为大家认为眼前遇到问题最 ...
- 卖油翁 欧阳修 无他,但手熟尔
陈康肃公尧咨善射,当世无双,公亦以此自矜.尝射于家圃,有卖油翁释担而立,睨之,久而不去.见其发矢十中八九,但微颔之. 康肃问曰:"汝亦知射乎?吾射不亦精乎?"翁曰:"无他 ...
- 编程思想:我亦无他,唯手熟尔
目录 一.编程思想三大定理 二.编程思想四大特性 三.做到高内聚,低耦合 (一)内聚 (二)耦合 一.编程思想三大定理 (1)思路分析,化繁为简:将需求拆成多个步骤实现,先完成基本功能和大致框架,在往 ...
- 算法唯手熟尔(PAT剩余清单 or leetcode)---希望可以日更
文章目录 2020/3/5 PAT A1119_C 2020/3/6 PAT A1123_C PAT A1115_C PAT A1114_C leetcode 206. 反转链表_C leetcode ...
- 算法唯手熟尔4月(PAT剩余清单 or leetcode)---希望可以日更
文章目录 2020/4/1 leetcode 914. 卡牌分组_Go leetcode 1111. 有效括号的嵌套深度_Go 2020/4/2 leetcode 289. 生命游戏_Go 2020/ ...
最新文章
- 版本服务器Svn部署与配置
- 动态修改easyui datagrid 列宽度
- 第十八讲 傅里叶变换
- 全球及中国家庭用空气净化器行业供需分析及发展营利模式预测报告2022-2027年
- 前端学习(2661):生命周期
- Postman从入门到入门
- 罗海雄:仅仅使用AWR做报告? 性能优化还未入门(含PPT)
- 为机场按上一双“慧眼”消灭飞机的“黑色十分钟”
- 嵌入式Linux系统编程学习之十八进程间通信(IPC)简介
- df满足条件的值修改_如何用python实现熵值法求指标权重(实例)
- 问题 | golang编程中的坑
- Linux 使用pid文件结束nginx
- fopen()及相关函数使用
- 查看计算机CPU核心数和线程数
- iOS6和iPhone5使用第三方静态库在真机无法运行的处理
- java对接钉钉发送消息通知
- Python str()函数
- 怎么写一个php脚本_php脚本怎么写
- Java正则表达式 - Matcher
- java爬虫实例_关于java爬虫以及一些实例
热门文章
- C#如何在Windows上接入蓝牙设备
- 电脑版美食大战老鼠放置html,美食大战老鼠电脑版
- Java自动装箱与自动拆箱(包装类)以及Integer和Double的valueOf()源码分析
- [转载]网络数据流的java处理
- 纯CSS实现四种方式文本反差色效果
- 计算一个数二进制中1的个数超全解法(C语言)
- python代码螺旋线怎么写_python实现画五角星和螺旋线的示例
- 零基础搭建自己的饥荒Don‘t Starve服务器,摆脱联机卡顿和小伙伴快乐联机
- 【2022牛客多校5 A题 Don‘t Starve】DP
- 2022可用的免费天气预报API接口