原文链接: http://hankerzheng.com/blog/Leetcode-Zuma-Game-

Problem Description

LeetCode 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:
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.
The number of balls on the table won’t exceed 20, and the string represents these balls is called “board” in the input.
The number of balls in your hand won’t exceed 5, and the string represents these balls is called “hand” in the input.
Both input strings will be non-empty and only contain characters ‘R’,’Y’,’B’,’G’,’W’.

中文大意:
祖玛游戏, 也就是QQ龙珠, 告诉你当前桌面上球的排列顺序以及你当前手上有的球, 求问当前手上的球是否能够完全消除桌面上的球, 如果能, 返回所需要球的最小个数; 如果不能, 返回-1

My Solution

English Version Post on LeetCode Discussion

Naive Solution (暴力解)

根据当前手上求球的颜色, 每次消除桌面上相同颜色的球, 然后递归, 直到桌面上没球了或者手上没球了. 最后统计当桌面上没球的时候, 花费球的数量.

暴力解, 很直接, 可以直接用backtracking来做. 但是问题在于每次消除一个颜色的球之后, 我们需要重构当前桌面的球, 比如如果此时桌面上面有 Y RR GG R YY, 我们手上有 G R Y. 当我们消除R的时候我们需要重构桌面上的球, 并且作为参数传递, 递归调用; 当我们消除G的时候, 我们不仅仅需要重构, 还需要判断当前桌面的球是否能自我销毁.

因此暴力解的每次递归都是一个O(n)时间复杂度的操作, 而暴力解本身是一个expoential solution, 两者一相乘, 这时间复杂度太美不敢看了.

Dynamic Programming Solution

首先预处理input string, 将桌面上的球转换为一个列表, 列表的每个元素表示连续相同颜色球的颜色和个数, 并且预处理时, 可以直接消除相同颜色超过三个以上的球. 因此, 对于RRBBBGYYWWWYB, 转化后的表示为[["R", 2], ["B", 3], ["G", 1], ["B", 1]].
当前问题的最优解有以下三种可能性:
- 将当前区间分割为两个部分, 两个部分的最优解合并, 即可得到当前问题的解
- 如果当前区间第一个颜色和最后一个颜色相同, 那么第一个色块和最后一个色块可以最后合并. 当前问题的解, 即为中间区间的最优解, 加上第一个色块和最后一个色块合并后新问题的解.
- 如果当前区间第一个颜色和最后一个颜色相同, 并且两个色块合并后个数小于3, 并且存在中间相同颜色个数为1的色块, 那么这三个分离的色块可以合并并消除. 因此, 问题的解即为分割后, 剩下两个色块的最优解.

上述三种情况涵盖了所有的可能性. 该算法的时间复杂度为O(N^3), 其中N表示色块的个数.

class Solution(object):def findMinStep(self, board, hand):""":type board: str:type hand: str:rtype: int"""def getBalls(balls):"""Convert the init given board string into a ball list.Each element of the list is in the form of [color, ballCnt]This function can automatically clear the 3 consective balls withthe same color in the given string.>>> getBalls("RRBBBGYYWWWYB")[["R", 2], ["B", 3], ["G", 1], ["B", 1]]"""ballList = []for ball in balls:if not ballList or ballList[-1][0] != ball:if ballList and ballList[-1][1] >= 3:ballList.pop(-1)ballList.append([ball, 1])elif ball == ballList[-1][0]:ballList[-1][1] += 1return ballListdef combineBalls(balls1, balls2):"""Combine 2 sets of balls together.>>> combineBalls({"R": 1}, {"R": 1, "G": 1}){"R": 2, "G": 1}"""ans = dict(balls1)for key, value in balls2.items():if key in ans:ans[key] += valueelse:ans[key] = valuereturn ansdef cntBalls(balls):"""Count the number of balls we have chosen.Since there is only 5 colors in the game, this function can be done in O(1) time."""return sum(balls.values())def updateAns(ans1, ans2):"""Compare two different solution to the sub-problem,and return the better one.If `ans1` has fewer balls and `ans1` can be formed by the balls given,then just return `ans1`, else we return `ans2`Therefore, `ans1` should always be the new soluton, while `ans2` the old."""if cntBalls(ans1) < cntBalls(ans2) and checkAvailable(ans1, ballsInHand) >= 0:return ans1return ans2def checkAvailable(balls, ballsInHand):"""Check whether current balls is available according to the given balls.Since there is only 5 colors in the game, this function can be done in O(1) time."""for key, value in balls.items():if balls[key] != 0:if key not in ballsInHand:return -1if ballsInHand[key] < value:return -1return sum(balls.values())def memorySearch(start, end):if end < start:return {}elif (start, end) in history:return history[(start, end)]elif start == end:return {ballsTable[start][0]: 3 - ballsTable[start][1]}elif start + 1 == end:return combineBalls(memorySearch(start, start), memorySearch(end, end))thisAns = {"R":float("inf")}firstColor, lastColor = ballsTable[start][0], ballsTable[end][0]# The first possible Solution is to split the balls into 2 parts and finish both of them seperatelyfor k in xrange(start, end):thisBalls = combineBalls(memorySearch(start, k), memorySearch(k+1, end))thisAns = updateAns(thisBalls, thisAns)# The second possible Solution is to clear the first and the last balls in the endif firstColor == lastColor:toAdd = max(0, 3 - ballsTable[start][1] - ballsTable[end][1])thisBalls = combineBalls(memorySearch(start+1, end-1), {firstColor: toAdd})thisAns = updateAns(thisBalls, thisAns)# The third possible Solution is to clear the first and the last balls in the end with# one ball in the middleif firstColor == lastColor and 1 in (ballsTable[start][1], ballsTable[end][1]):idx = start + 1while idx < end:if ballsTable[idx][0] == firstColor and ballsTable[idx][1] == 1:thisBalls = combineBalls(memorySearch(start + 1, idx - 1), memorySearch(idx + 1, end - 1))thisAns = updateAns(thisBalls, thisAns)idx += 1history[(start, end)] = thisAnsreturn thisAns# InitializationballsTable = getBalls(board)ballsInHand = {}for ball in hand:ballsInHand[ball] = ballsInHand.get(ball, 0) + 1history = {}length = len(ballsTable)return checkAvailable(memorySearch(0, length - 1), ballsInHand)

LeetCode 488 Zuma Game 解题报告相关推荐

  1. 【LeetCode】3Sum Closest 解题报告

    [题目] Given an array S of n integers, find three integers in S such that the sum is closest to a give ...

  2. LeetCode Maximum Product Subarray 解题报告

    LeetCode 新题又更新了.求:最大子数组乘积. https://oj.leetcode.com/problems/maximum-product-subarray/ 题目分析:求一个数组,连续子 ...

  3. [leetcode]488. Zuma Game

    题目链接:https://leetcode.com/problems/zuma-game/description/ Think about Zuma Game. You have a row of b ...

  4. 【LeetCode】77. Combinations 解题报告(Python C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:递归 方法二:回溯法 日期 题目地址:htt ...

  5. [leetcode] 28. Implement strStr() 解题报告

    题目链接:https://leetcode.com/problems/implement-strstr/ Implement strStr(). Returns the index of the fi ...

  6. 【LeetCode】Palindrome Partitioning 解题报告

    [题目] Given a string s, partition s such that every substring of the partition is a palindrome. Retur ...

  7. LeetCode 705 Design HashSet 解题报告

    题目要求 Design a HashSet without using any built-in hash table libraries. To be specific, your design s ...

  8. LeetCode: First Missing Positive 解题报告

    Q: Given an unsorted integer array, find the first missing positive integer. For example, Given [1,2 ...

  9. [Leetcode] 625. Minimum Factorization 解题报告

    题目: Given a positive integer a, find the smallest positive integer b whose multiplication of each di ...

最新文章

  1. 面试官:谈一下你对DDD的理解?我:马什么梅?
  2. c语言表达式用法,C语言开发之运算符、表达式用法
  3. JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记3
  4. Struts2理解——转发和重定向
  5. Spring--总体架构
  6. SIMD学习 -- 用SSE2指令作点乘和累加计算
  7. android:layout_width=0.0dip,【教程】状态栏显示网速
  8. linux里怎样压缩文件,如何在Linux中解压缩文件
  9. pycharm 初级使用文档
  10. 编译OpenJDK12:LNK2019 无法解析的外部符号sprintf
  11. 树莓派-迅雷远程下载
  12. 【Python】发送UDP数据(保姆级图文+附测试工具文件+api例程)
  13. 【转】关于PCI和PCIE
  14. 如何删除在System中打开的iso文件
  15. win7计算机双击变管理,如何修复Win7系统鼠标单击以双击
  16. 人体手脚部位与内脏的对应关系图
  17. 【shell】【sed】在行前/行后插入一新行
  18. 计算机基础操作测试题,计算机基础操作练习题.pdf
  19. 杭电计算机导师6,杭州电子科技大学计算机学院导师教师师资介绍简介-贾刚勇...
  20. 游戏反外挂技术原理讲解

热门文章

  1. maya arnold渲染带有金光雕像渲染测试
  2. 飞凌OK335xS开发平台软件测试
  3. 2022-2028年中国天然橡胶行业市场发展现状及竞争格局预测报告
  4. 2013福建高职单招计算机类专业,福建省2013高职单招计算机类试题及答案
  5. L3-039. 古风排版 (点一下其中几个易错的坑)
  6. 一款神奇的国产便携式扩音器
  7. Contest3117 - 2021级新生个人训练赛第24场_问题 E: 打印方阵
  8. 后盾网-CI框架实例教程-马振宇 - 学习笔记(6)
  9. c语言程序设计工资纳税系统,c语言程序设计,纳税工资系统(29页)-原创力文档...
  10. hybrid app开发教程