Leetcode 488. 祖玛游戏 DFS

題目 https://leetcode-cn.com/problems/zuma-game/
这题根据题目我们可知,就是消去连着的球,然后剩下的球再就是一样的处理,最后消完后再去比较最小值
这是一道DFS题目,为什么用DFS呢? 因为我们可以去遍历board字符串,去看下哪些球缺多少个相同的球,然后再用我们手里的球去填充。
至于手里的球hand,我们可以用Map去存下每种球有多少个。

对于这道题来说,我们不能像游戏那样,把中间球消除后,左右两边合起来刚好又消掉。对于这样的情况,可能不是最优解。例如下图:
在这里插入图片描述
图中只列举几种情况。
如我们所看,对于前面那种消去WW之后,剩余RRRRBBRR,我们这时
消去前面的RRRR就不能消去全部的了。
但是我们像后面的那种,消去后面的BB,剩下RRWWRRRR,因为每次消去后,都是从前面开始遍历的,所以后面的还不会合并,因此这种成为最优解

class Solution {
    Map<Character,Integer> map;
    int res=10;			//手上的球最多5个,所以设定为10
    public int findMinStep(String board, String hand) {
        if(hand==null||hand.length()==0) return -1;
        map=new HashMap();
        for(char c:hand.toCharArray())
            map.put(c,1+map.getOrDefault(c,0));
        dfs(board,0);
        return res==10?-1:res;
    }
    void dfs(String board,int sum){
        if(board.equals("")) res=Math.min(res,sum);
        int n=board.length();
        int i=0,j=0;
        while(i<n){
            char c=board.charAt(i);
            j=i+1;
            while(j<n&&board.charAt(i)==board.charAt(j))
                j++;
            int num=j-i;
            //不能消掉的球
            if(num<3){
                Integer cnt=map.get(c);
                //需要的球数量
                int need=3-num;
                if(cnt!=null&&cnt>=need){
                    String str=board.substring(0,i)+board.substring(j);
                    map.put(c,cnt-need);
                    dfs(str,sum+need);
                    map.put(c,map.get(c)+need);
                }
            }
            //可以消去
            else{
                dfs(board.substring(0,i)+board.substring(j),sum);
            }
            //往后遍历
            i=j;
        }
    }
}

主要知道怎么往下走,条件是什么,而且这类题跟回溯一样,深搜下去,回来的时候要状态回转。
简单的模板:

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        dfs();
        return ans;
    }
    dfs(){
        //终止条件
        if()    ....;

        //按顺序访问分支点
        {
            //本节点处理
            //进入下一节点
            //回溯,状态重置(具体情况,有些需要,有些不需要)
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值