力扣原题,java代码

解法一:广度优先

暴力求解思想:枚举所有的情况,依次取出手中的球,将之插入到桌面不同位置。故而每次迭代中,我们只需要记录两个变量即可,即当前桌面球的信息以及手中球的信息。

初始化队列信息:

Queue<String[]> q = new LinkedList<>();
q.add(new String[]{board,hand});

当桌面上的球全部被移除时,游戏结束返回使用球的数量;

当手中的球全部使用完,但桌面上的球仍旧未被移除完,此种情况不可行。

如果穷举所有情况,代码一定会超时,故而可以采取一些减枝策略:

1.对于手中的球而言,每次插入时,相同颜色的球只需考虑一次

2.插入球时只需考虑两种情况

①若插入的球与后一位颜色相同,则可以将球插入,之后与该球颜色相同的连续位置不再考虑球的插入(例如当board = "RBBWWBB"时,将颜色为B的球插入到board时,将球插入到索引位置1, 2, 3的情况是一样的,所以我们只需靠将球插入到1的情况即可,另外2种可以跳过,节省运行时间)

②若插入的球与后一位颜色不一致,那么桌面上球插入的后一位和前一位球一定要一致或者球插入的位置就是桌面球位置的最前端(例如当board = "RRWWRRBBRR", hand = "WB"时,先将B颜色的球插入到第一组"RR"之间使得board = "RBRWWRRBBRR",再将W小球插入到"WW"前面,这样就可以使得board上全部的小球被移除。将B防止在"RR"之间阻隔了两组"RR"相遇,造成四个R被移除,而剩余的两个R无法被移除的情况)

为了更进一步的减少计算时间,我们还可以在程序中加入记忆搜索和A*算法。

记忆搜索:对于每种情况,桌面上球的信息需要全部考虑,但手中球的信息我们只需要考虑不同颜色球的个数即可。故而每种情况我们用一个字符串来记录,将当前已知的所有情况存储在HashMap中,并记录当前情况花费球的个数,若后期探索过程中遇到同样的情况,则只需保留花费球数量最少的情况即可。

A*算法:队列中每种情况除了记录桌面球的信息和手中球不同颜色球的数量外,还需要记录当前花费球的数量cur。引入A*算法后,需要再添加一个信息,即将当前board中所有的小球移除,预计花费的代价eva。使用优先队列存储每种情况的信息,优选探索cur+eva值最小的情况,当board中所有球被移除时,此时的cur即是我们要求的最少球数量,因为队列中其他情况的cur+eva皆大于当前情况的cur,这说明,其他情况最少需要花费球的数量都大于当前情况花费球的数量,故而当前情况花费球的数量就是最小的!(备注:当手中的球一定无法将当前桌面的球全部移除时,这种情况不再探索)

class Solution {class Node {String b;int[] colorNumber;int cur; // 当前代价int eva; // 预期代价Node(String b, int[] colorNumber, int cur, int eva) {this.b = b;this.colorNumber = colorNumber.clone();this.cur = cur;this.eva = eva;}}// 消除当前Board上所有彩球,最少需要的代价public int evaluate(String b, int[] colorNumber) {int[] bx = new int[5];for (int i = 0; i < b.length(); i++) {bx[cn.get(b.charAt(i))]++;}int count=0;for (int i = 0; i < 5; i++) {if(bx[i]>0 && bx[i]<3) {if(colorNumber[i] + bx[i] < 3) {return -1; // 不可行} else {count += 3-bx[i];}}}return count;}HashMap<Character,Integer> cn;  // RYBGW 01234public int findMinStep(String board, String hand) {// 升序PriorityQueue<Node> q = new PriorityQueue<>((a, b)->(a.cur+a.eva)-(b.cur+b.eva));int n = hand.length(); // 球的总数int[] colorNumber = new int[5]; // 五种颜色的球的数量char[] color = new char[]{'R','Y','B','G','W'};cn = new HashMap<>();for (int i = 0; i < 5; i++) {cn.put(color[i],i);}for (int i = 0; i < hand.length(); i++) {colorNumber[cn.get(hand.charAt(i))]++;}q.add(new Node(board, colorNumber,0,evaluate(board,colorNumber)));HashMap<String,Integer> map = new HashMap<>(); // 已有的状态map.put(merge(board,colorNumber),0);while (!q.isEmpty()) {Node node = q.poll();char[] b = node.b.toCharArray();int len = b.length; // 桌面上球剩余数量int cur = node.cur+1;int[] h = node.colorNumber;for (int i = 0; i < 5; i++) {char c = color[i];if(h[i] <= 0) {continue;}int[] hnew = h.clone(); hnew[i]--;int k=0;while (k<len) {if(c != b[k] && (k==0 || b[k-1] != b[k])) {k++;continue;}String bnew = insert(node.b,c,k);int eva = evaluate(bnew,hnew);if(bnew.equals("")) {return cur;}if(eva >= 0) {String state=merge(bnew,hnew);if(!map.containsKey(state) || map.get(state) > cur) {q.add(new Node(bnew,hnew,cur,eva));map.put(state,cur);}}while (k<len && c == b[k++]);}}}return -1;}public String merge(String a, int[] colorNumber) {String state = a;for (int i = 0; i < 5; i++) {state += colorNumber[i];}return state;}// 将球c插入位置ipublic String insert(String board, char c, int k) {int n = board.length();board = board.substring(0,k)+c+board.substring(k,n);if(board.length() > 2) {board = eliminate(board,k,k);}return board;}// 消除public String eliminate(String board, int i, int j) {int n = board.length();char c = board.charAt(i);while (i-1>=0 && c == board.charAt(i-1)) {i--;}while (j+1<n && c == board.charAt(j+1)) {j++;}if(j-i>1) {board = board.substring(0,i)+board.substring(j+1,n);if(board.length() > 2) {i = i>0?i:1;board = eliminate(board,i-1,i-1);}}return board;}
}

祖玛游戏(记忆搜索+A*算法)相关推荐

  1. ​LeetCode刷题实战488:祖玛游戏

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

  2. 2021-11-09祖玛游戏

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

  3. LeetCode 488. 祖玛游戏

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

  4. 面试官:祖玛游戏玩过么?我来拷拷你~

    题目地址(488. 祖玛游戏) https://leetcode-cn.com/problems/zuma-game/ 题目描述 回忆一下祖玛游戏.现在桌上有一串球,颜色有红色(R),黄色(Y),蓝色 ...

  5. 五子棋html游戏代码与算法介绍

    五子棋html游戏代码与算法介绍 运行图片 目录路径 五子棋.html 五子棋算法 进行下一个游戏的开发! 注意事项 我会把html文件.css文件提供下载地址,文件夹路径也展示给大家.但是图片就没法 ...

  6. LeetCode-笔记-45.跳跃游戏II-贪心算法

    LeetCode-笔记-45.跳跃游戏II-贪心算法 给定一个非负整数数组,你最初位于数组的第一个位置. 数组中的每个元素代表你在该位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后 ...

  7. HTML五子棋游戏代码介绍,五子棋html游戏代码与算法介绍

    五子棋html游戏代码与算法介绍 我会把html文件.css文件提供下载地址,文件夹路径也展示给大家.但是图片就没法一一放在博客里面了. 大家有需要的话,加博主QQ:2864144286,全天在线. ...

  8. qt实现扫雷游戏一:算法实现

    qt实现扫雷游戏一:算法实现 说明 问题总结 目录 算法文件 头文件 源文件 说明 借助qt写了一个扫雷程序,记录一下. 这是这两天用qt写扫雷所做的一些事情,在这里总结一下,另外,源代码和整个工程已 ...

  9. JAVA算法:李白遇花喝酒游戏JAVA DFS 算法设计

    JAVA算法:李白遇花喝酒游戏JAVA DFS 算法设计 看到了这样的一道题目,还挺有意思,可以通过不同的算法设计来求解. 话说大诗人李白,一生好饮.一日,他提着酒壶,从家里出来,酒壶中有酒2斗.他边 ...

  10. Visual C++实现推箱子游戏的核心算法设计与实现(附源码和和资源)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 在前面的博客中已经讲解了推箱子游戏的菜单和各种对话框的实现,下面对推箱子游戏的核心算法设计和实现进行讲解 一.地图文件读取模块的设计与实现 地图文件 ...

最新文章

  1. js_sqlite_ADODB.Connection
  2. 参加51CTO培训,PMP考试通过啦
  3. 数据结构与算法-链表
  4. Spring Boot基本配置
  5. 手机:导致手机发烫的原因有哪些?
  6. 计算机图形学图形旋转_计算机图形学中的平板显示
  7. android聊天,存储聊天记录sqlite
  8. 不同的二叉搜索树 II
  9. Android Bitmap 加载与像素操作
  10. Alpine Linux:如何配置GUI的图形桌面环境:x Desktop Environment
  11. ecshop /goods.php SQL Injection Vul
  12. linux系统安装gaussview_Linux系统安装Python
  13. Hadoop3.3.1详细教程(四)Linux集群搭建+免密登录
  14. 怎么下载并使用向日葵远程工具
  15. 下划线命名法 vs 驼峰命名法
  16. Perl之正则表达式基础(一)
  17. position常用属性值
  18. Virtualbox如何配置Linux的网络连接
  19. $Self~Problem~C~:~Samsara$
  20. Inno Setup打包实现安装自启和开机自启

热门文章

  1. 牛客网趋势最热Java八股文,已帮助上千人拿到大厂offer
  2. BugFree 2.0.3使用帮助
  3. 左右切换箭头代替滚动条,实现类似走马灯效果
  4. SaaSBase:什么是Thoughts?
  5. RSA算法原理(一)
  6. FLAH中影片剪辑与图形元件的不同应用
  7. 从永辉超市2020年上半年财报看其强大的生鲜供应链系统数字化
  8. Laravel 清空 Redis 队列
  9. PostgreSQL的“孔雀开屏”式程序架构
  10. AppScan的用法