leetcode403青蛙过河

这篇博客探讨了如何将广度优先搜索(BFS)转化为记忆化搜索(DFS)和动态规划(DP)来解决石子跳跃问题。作者首先介绍了初始的BFS实现,然后逐步优化,通过引入记忆化搜索降低时间复杂度,并最终将问题转换为动态规划的形式。博客中包含了多个代码示例,展示了如何使用HashMap作为记忆化存储以提高效率。
摘要由CSDN通过智能技术生成

关于动态规划和bfs似乎找到一点点门路

**//用dfs做
//记忆化搜索+dfs
//考虑加入记忆化,将可变参数作为维度,返回值作为存储值

//从bfs到动态规划:dp[][]=可变参数

//使用数组作为中间结果的缓存容器
//boolean[石子列表下标][跳跃步数]//均为可变参数也就是i和k
//为了区分状态是否计算int[石子列表下标][跳跃步数] 0:未计算 1:计算true -1:计算false
//确定容器维度:2 <= stones.length <= 2000 确定为int[2009][2009]
//维度太大,改为HashMa**p
class Solution {
     private int[] k;
    private int[] stones;
    Map<Integer, Integer> map;

    public boolean canCross(int[] stones) {
     if(stones[1]!=1) return false;
        map = new HashMap<>();
        for (int i = 0; i < stones.length; i++) {
            map.put(stones[i], i);
        }
        this.stones = stones;
        return dfs3();
    }

    //dfs+记忆化的另一种方式:dfs标记
    public boolean dfs3() {
        int n = stones.length;
        boolean[][] vis = new boolean[n][n];
        Deque<int[]> deque = new ArrayDeque<>();
        vis[1][1] = true;
        deque.addLast(new int[]{1, 1});

        while (!deque.isEmpty()) {
            int[] poll = deque.poll();
            int index = poll[0];
            int k = poll[1];
            if (index == n - 1) return true;
//就是把可以走到的都记录下来
               int num = stones[index] + k;
            if (k - 1 > 0 && map.containsKey(num - 1)) {
                //寻找下一个
                int nextIndex = map.get(num - 1);
                if (nextIndex==n-1) return true;
               if (!vis[nextIndex][k-1]){
                   vis[nextIndex][k-1]=true;
                   deque.addLast(new int[]{nextIndex,k-1});
               }
            }
            if (map.containsKey(num)) {
                int nextIndex = map.get(num);
                if (nextIndex==n-1) return true;
                if (!vis[nextIndex][k]){
                    vis[nextIndex][k]=true;
                    deque.addLast(new int[]{nextIndex,k});
                }
            }
            if (map.containsKey(num + 1)) {
                int nextIndex = map.get(num + 1);
                if (nextIndex==n-1) return true;
                if (!vis[nextIndex][k+1]){
                    vis[nextIndex][k+1]=true;
                    deque.addLast(new int[]{nextIndex,k+1});
                }
            }

        }
        return false;
    }

    /*
  private int[] k;
    private int[] stones;
    Map<Integer,Integer> map;
    public boolean canCross(int[] stones) {
       if(stones[1]!=1) return false;
         map=new HashMap<>();
        for(int i=0;i<stones.length;i++){
            map.put(stones[i],i);
        }
        this.stones=stones;
      return dfs1(1,stones[1]);
    }
    **//用dfs做
    //记忆化搜索+dfs
    //考虑加入记忆化,将可变参数作为维度,返回值作为存储值
    //从bfs到动态规划:dp[][]=可变参数
    //使用数组作为中间结果的缓存容器
    //boolean[石子列表下标][跳跃步数]//均为可变参数也就是i和k
    //为了区分状态是否计算int[石子列表下标][跳跃步数] 0:未计算 1:计算true -1:计算false
    //确定容器维度:2 <= stones.length <= 2000 确定为int[2009][2009]
    //维度太大,改为HashMap**
    Map<String,Boolean> cache=new HashMap<>();
    public boolean dfs1(int index,int k){
        String key=index+"_"+k;
        if (cache.containsKey(key)) return cache.get(key);
        if (index==stones.length-1) return true;

        int num=stones[index]+k;
        if(k-1>0&&map.containsKey(num-1)){
            //寻找下一个
            int nextIndex=map.get(num-1);
            boolean cur=dfs1(nextIndex,k-1);
            cache.put(key,cur);
            if(cur) return true;
        }
        if (map.containsKey(num)){
            int nextIndex=map.get(num);
            boolean cur= dfs1(nextIndex,k);
            cache.put(key,cur);
            if(cur) return true;
        }
        if (map.containsKey(num+1)){
            int nextIndex=map.get(num+1);
            boolean cur= dfs1(nextIndex,k+1);
            cache.put(key,cur);
            if(cur) return true;
        }
        cache.put(key,false);
        return false;
    }
    */
    /*
    //第一版bfs,时间复杂度很高
    private int[] k;
    private int[] stones;
    Map<Integer,Integer> map;
    public boolean canCross(int[] stones) {
        if(stones.length==2&&stones[1]>1) return false;
         map=new HashMap<>();
        for(int i=0;i<stones.length;i++){
            map.put(stones[i],i);
        }
        this.stones=stones;
      return dfs(1,1);
    }
    //用dfs做
//初始dfs
    public boolean dfs(int i,int k){
        if (i==stones.length-1){
            return true;
        }

        //结束条件
        int num=stones[i]+k;
        if(k-1>0&&map.containsKey(num-1)){
            //寻找下一个
            int nextIndex=map.get(num-1);
            boolean cur=dfs(nextIndex,k-1);
            if(cur) return true;
        }
        if (map.containsKey(num)){
            int nextIndex=map.get(num);
           boolean cur= dfs(nextIndex,k);
           if(cur) return true;
        }
        if (map.containsKey(num+1)){
            int nextIndex=map.get(num+1);
            boolean cur= dfs(nextIndex,k+1);
            if(cur) return true;
        }
        return false;

    }
    */

    /*
public boolean canCross(int[] stones) {
//动态规划
        int n=stones.length;
        boolean[][] dp=new boolean[n][n+1];//dp[i][k]:表示从前面的j跳到i,跳k步可以跳到
        dp[0][0]=true;
        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++){
                int k=stones[i]-stones[j];//表示需要跳k步
                if(k<n&&k<=stones[j]+1) {
                    dp[i][k] = dp[j][k - 1] || dp[j][k] || dp[j][k + 1];
                    if (i == n - 1 && dp[i][k] == true) return true;
                }
            }
        }
        return false;
        
    }
    */
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值