算法奇妙屋(三十三)-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;
    }
}
相关推荐
小O的算法实验室12 小时前
2026年ASOC,基于深度强化学习的无人机三维复杂环境分层自适应导航规划方法,深度解析+性能实测
算法·无人机·论文复现·智能算法·智能算法改进
郭涤生13 小时前
STL vector 扩容机制与自定义内存分配器设计分析
c++·算法
༾冬瓜大侠༿13 小时前
vector
c语言·开发语言·数据结构·c++·算法
Ricky111zzz14 小时前
leetcode学python记录1
python·算法·leetcode·职场和发展
汀、人工智能14 小时前
[特殊字符] 第58课:两个正序数组的中位数
数据结构·算法·数据库架构··数据流·两个正序数组的中位数
liu****14 小时前
第16届省赛蓝桥杯大赛C/C++大学B组(京津冀)
开发语言·数据结构·c++·算法·蓝桥杯
汀、人工智能14 小时前
[特殊字符] 第79课:分割等和子集
数据结构·算法·数据库架构·位运算·哈希表·分割等和子集
汀、人工智能14 小时前
[特殊字符] 第74课:完全平方数
数据结构·算法·数据库架构·图论·bfs·完全平方数
CoderCodingNo14 小时前
【GESP】C++四、五级练习题 luogu-P1177 【模板】排序
数据结构·c++·算法
Proxy_ZZ014 小时前
从零实现LDPC比特翻转译码器:C语言实战与底层逻辑解析
c语言·算法