Leetcode--773滑动谜题

芜湖,今天的困难题也做出来了!!!和昨天一样,缓存所有的可能,然后直接查询即可,查得到返回对应的值,查不到返回-1;
在这里插入图片描述在这里插入图片描述

思路

因为从状态2到状态1需要的滑动次数和从状态1到状态2需要的滑动次数相等,所以从123450开始滑动,记录所有的可能性和对应的次数,然后每次查询即可。
为了方便计算,将二维数组转化为字符串进行操作。
试验得出共有359种可能,最大的移动次数为21次。
算法步骤:

  1. 首先把数组转为字符串;
  2. 因为只有0的索引在0-2才可以向下移动、在3-5才可以向上、在不为0和3才可以向左、在不为2和5才可以向右;
  3. 因为map是实时变化的,所以为了避免map变化引起计算的错误,实验indicate指明当前计算的层次,map中的key存储可能的字符串,value存储需要的次数;
  4. 在得到所有可能性后,首先把要检测的数组转为字符串,然后查询其是否在map在,在的话则返回对应的value,否则返回-1;

代码

class Solution {
    static Map<String, Integer> map_slid;
    public void preCount()
    {
        Map<String, Integer> map_slid1 = new ConcurrentHashMap<>();
        String str = "123450";
        map_slid1 = new ConcurrentHashMap<>();
        map_slid1.put(str,0);
        int count = 1;
        int indicate = 0;
        while(count<360)
        {
            for (String i : map_slid1.keySet())
            {
                if (map_slid1.get(i)==indicate)
                {//获取0的位置
                    int index = i.indexOf('0');
                    int step = map_slid1.get(i);
                    //判断四个方向是否可以进行交换
                    //上
                    if (index>2)
                    {
                        String ss = i.substring(0,index-3) + '0' + i.substring(index-2,index) + i.charAt(index-3);
                        if (index+1<6)
                            ss += i.substring(index+1,6);
                        if (!map_slid1.containsKey(ss))
                        {
                            map_slid1.put(ss,step+1);
                            count++;
                        }
                    }
                    //下
                    if (index<3)
                    {
                        String ss = i.substring(0,index) + i.charAt(index+3) + i.substring(index+1,index+3) + '0';
                        if (index+4<6)
                            ss += i.substring(index+4,6);
                        if (!map_slid1.containsKey(ss))
                        {
                            map_slid1.put(ss,step+1);
                            count++;
                        }
                    }
                    //左
                    if ((index!=0) && (index!=3))
                    {
                        String ss = i.substring(0,index-1) + '0' + i.charAt(index-1);
                        if (index+1<6)
                            ss += i.substring(index+1,6);
                        if (!map_slid1.containsKey(ss))
                        {
                            map_slid1.put(ss,step+1);
                            count++;
                        }
                    }
                    //右
                    if ((index!=2) && (index!=5))
                    {
                        String ss = i.substring(0,index) + i.charAt(index+1)+ '0';
                        if (index+2<6)
                            ss += i.substring(index+2,6);
                        if (!map_slid1.containsKey(ss))
                        {
                            map_slid1.put(ss,step+1);
                            count++;
                        }
                    }}
            }
            indicate++;
        }

        map_slid=map_slid1;
    }

    public int slidingPuzzle(int[][] board) {
        //问题可以简化为--先把所有的可能性计算出来,直接进行匹配即可
        preCount();
        String input = "";
        for (int[] i : board)
            for (int j : i)
                input += String.valueOf(j);

        return map_slid.get(input)==null?-1:map_slid.get(input);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值