算法奇妙屋(三十三)-DFS的记忆化搜索

文章目录

在文章子序列问题 和 不同路径问题 中, 有题目的动态规划解法

一. 力扣 509. 斐波那契数

1. 题目

斐波那契数列相信大家已经很熟悉了, 这里就不过多赘述

2. 算法原理

看下图递归图我们可以发现, 有多次重复值的计算, 这里我们可以用一种容器来将已经计算好的斐波那契数存储起来, 在递归过程中就可以先去容器中看一下, 如果存在, 直接返回即可

3. 代码

java 复制代码
class Solution {
    int[] memory = new int[31];
    public int fib(int n) {
        for (int i = 0; i < 31; i++) {
            memory[i] = -1;
        }
        return dfs(n);
    }
    int dfs(int n) {
        if (memory[n] != -1) {
            return memory[n];
        }
        if (n == 0 || n == 1) {
            memory[n] = n;
            return memory[n];
        }
        memory[n] = dfs(n - 1) + dfs(n - 2);
        return memory[n];
    }
}

二. 力扣 62. 不同路径

1. 题目解析

题目较简单, 只能走两个方位, 和斐波那契数基本一样

2. 算法原理

3. 代码

java 复制代码
class Solution {
    int[][] memory;
    public int uniquePaths(int m, int n) {
        memory = new int[m + 1][n + 1];
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                memory[i][j] = -1;
            }
        }
        return dfs(m, n);
    }
    int dfs(int i, int j) {
        if (memory[i][j] != -1) {
            return memory[i][j];
        }
        if (i == 0 || j == 0) {
            memory[i][j] = 0;
            return 0;
        }
        if (i == 1 && j == 1) {
            memory[i][j] = 1;
            return 1;
        }
        memory[i][j] = dfs(i - 1, j) + dfs(i, j - 1);
        return memory[i][j];
    }
}

三. 力扣 375. 猜数字大小 II

1. 题目解析

2. 算法原理

3. 代码

java 复制代码
class Solution {
    int[][] memo;
    public int getMoneyAmount(int n) {
        memo = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                memo[i][j] = -1;
            }
        }
        return dfs(1, n);
    }
    int dfs(int left, int right) {
        if (left >= right) {
            return 0;
        }
        if (memo[left][right] != -1) {
            return memo[left][right];
        }
        int min = 0x3f3f3f3f;
        // 从left到right选节点
        for (int i = left; i <= right; i++) {
            int x = dfs(left, i - 1); // 去左子树找值
            int y = dfs(i + 1, right);// 去右子树找值
            min = Math.min(min, (Math.max(x, y) + i));  
        }
        memo[left][right] = min;
        return min;
    }
}

四. 力扣 300. 最长递增子序列

1. 题目解析

重点要知道子序列可以不连续

2. 算法原理

3. 代码

java 复制代码
class Solution {
    int[] memo;
    int n;
    public int lengthOfLIS(int[] nums) {
        n = nums.length;
        memo = new int[n];
        for (int i = 0; i < n; i++) {
            memo[i] = -1;
        }
        // 求多个起点开始的最长长度
        int max = 0;
        for (int i = 0; i < n; i++) {
            max = Math.max(dfs(nums, i), max);
        }
        return max;
    }
    int dfs(int[] nums,int pos) {
        if (memo[pos] != -1) {
            return memo[pos];
        }
        // 将其设置为1是因为自身也是一个数字,最小为1
        int max = 1;
        for (int i = pos + 1; i < n; i++) {
            if (nums[i] > nums[pos]) {
                max = Math.max(dfs(nums, i) + 1, max);
            }
        }
        // 最大值才是pos位置需要的值
        memo[pos] = max;
        return max;
    }
}

五. 力扣 329. 矩阵中的最长递增路径

1. 题目解析

这道题相当于求递增子序列的升级版, 这里可以上下左右四个方位走

2. 算法原理

3. 代码

java 复制代码
class Solution {
    int[][] memo;
    int m, n;
    int[] dx = {1, -1, 0, 0};
    int[] dy = {0, 0, -1, 1};
    public int longestIncreasingPath(int[][] matrix) {
        m = matrix.length;
        n = matrix[0].length;
        memo = new int[m][n];
        int max = 1;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                max = Math.max(max, dfs(matrix, i, j));
            }
        }
        return max;
    }
    int dfs(int[][] matrix, int i, int j) {
        if (memo[i][j] != 0) {
            return memo[i][j];
        }
        int max = 1;
        for (int k = 0; k < 4; k++) {
            int x = i + dx[k];
            int y = j + dy[k];
            if (x >= 0 && x < m && y >= 0 && y < n && matrix[i][j] < matrix[x][y]) {
                max = Math.max(max, dfs(matrix, x, y) + 1);
            }
        }
        memo[i][j] = max;
        return max;
    }
}
相关推荐
Doubbbbbbble云2 小时前
基于贪心算法的区间覆盖问题求解策略4
算法·贪心算法
不会就选b8 小时前
算法日常・每日刷题--<贪心>25
数据结构·算法
千里码aicood12 小时前
基于CART算法的图书分类系统设计与实现
数据库·算法·分类
做cv的小昊12 小时前
【World Model】π0.5:a Vision-Language-Action Model with Open-World Generalization
人工智能·算法·机器学习·大模型·多模态·vla·世界模型
لا معنى له13 小时前
World-In-World: World Models in a Closed-Loop World
算法
Discipline102915 小时前
尼泊尔河流流量:天气驱动的预测与高流量风险
人工智能·算法
XuCoder15 小时前
改一个数,右边全得重算,这题怎么扛住两万次查询
算法
小羊没烦恼!15 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#
weixin_3077791316 小时前
基于睿擎工业开发平台的预训练视觉模型轻量化适配与低代码部署优化
开发语言·算法