【leetcode】记忆化搜索


一、斐波那契数

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

常规递归暴搜代码:

class Solution
{
   
public:
	int fib(int n)
	{
   
		if(n == 0) return 0;
		if(n == 1) return 1;
		return fib(n - 1) + fib(n - 2);
	}
};

备忘录版:

class Solution 
{
   
public:
    // 备忘录
    int memo[31];
    int fib(int n) 
    {
   
        memset(memo, -1, sizeof(memo)); // 先将备忘录进行初始化为-1,因为-1根本就不会遇到
        return dfs(n);
    }
    int dfs(int n)
    {
   
        // 先判断一下在不在备忘录中
        if(memo[n] != -1) // 在备忘录中就用备忘录中的
        {
   
            return memo[n];
        }
        if(n == 0 || n == 1)
        {
   
            memo[n] = n;
            return n;
        }
        memo[n] = dfs(n - 1) + dfs(n - 2); // 返回之前先保存一下
        return memo[n];
    }
};

动态规划版本:

class Solution 
{
   
public:
    // dp表
    int dp[31];
    int fib(int n) 
    {
   
        dp[0] = 0;
        dp[1] = 1;
        for(int i = 2; i <= n; i++)
        {
   
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];    
    }
};

3、解析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、不同路径

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

记忆化搜索:

class Solution 
{
   
public:
    vector<vector<int>> memo;
    int uniquePaths(int m, int n) 
    {
   
        memo = vector<vector<int>>(m + 1, vector<int>(n + 1));
        return dfs(m, n);
    }
    int dfs(int i, int j)
    {
   
        if(memo[i][j] != 0)
        {
   
            return memo[i][j];
        }
        if(i == 0 || j == 0)
        {
   
            return 0; // 越界情况
        }
        if(i == 1 && j == 1)
        {
   
            memo[i][j] = 1;
            return 1;
        }
        memo[i][j] = dfs(i - 1, j) + dfs(i, j - 1);
        return memo[i][j];
    }
};

动态规划:

class Solution 
{
   
public:
    int uniquePaths(int m, int n) 
    {
   
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        dp[1][1] = 1;
        for(int i = 1; i <= m; i++)
        {
   
            for(int j = 1; j <= n; j++)
            {
   
                if(i == 1 && j == 1)
                {
   
                    continue;
                }
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m][n];
    }
};

3、解析

在这里插入图片描述

三、最长递增子序列

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

记忆化搜索:

class Solution 
{
   
public:
    int lengthOfLIS(vector<int>& nums) 
    {
   
        int n = nums.size();
        vector<int> memo(n); // 定义一个备忘录
        int ret = 0;
        for(int i = 0; i < n; i++)
        {
   
            ret = max(ret, dfs(i, nums, memo)); // 相信dfs一定能处理好往后进行遍历
        }
        return ret;
    }
    int dfs(int pos, vector<int>& nums, vector<int>& memo)
    {
   
        if(memo[pos] != 0) // 此处是已经使用过了
        {
   
            return memo[pos];
        }
        int ret = 1; // 必须从1开始,不然一直是0比较,会出现边界情况
        for(int i = pos + 1; i < nums.size(); i++)
        {
   
            if(nums[i] > nums[pos])
                ret = max(ret, dfs(i, nums, memo) + 1);
        }
        memo[pos] = ret; // 保存一下
        return memo[pos];
    }
};

动态规划做法:

class Solution 
{
   
public:
    int lengthOfLIS(vector<int>& nums) 
    {
   
        int n = nums.size();
        vector<int> dp(n, 1); // 定义一个有n个数为1的dp数组
        int ret = 0;
        // 从后往前遍历
        for(int i = n - 1; i >= 0; i--)
        {
   
            for(int j = i + 1; j < n; j++)
            {
   
                if(nums[j] > nums[i])
                {
   
                    dp[i] = max(dp[i], dp[j] + 1);
                }
            }
            ret = max(ret, dp[i]); // 每次更新一下
        }
        return ret;
    }
};

3、解析

在这里插入图片描述

四、猜数字大小II

1、题目描述

leetcode链接
在这里插入图片描述

2、代码

class Solution 
{
   
public:
    // 定义一个备忘录
    vector<vector<int>> memo;
    int getMoneyAmount(int n) 
    {
   
        memo = vector<vector<int>>(n + 1, vector<int>(n + 1));
        // 暴搜
        return dfs(1, n); // 传一个区间
    }
    int dfs(int left, int right)
    {
   
        if(left >= right) return 0;
        if(memo[left][right] != 0)
        {
   
            return memo[left][right];
        }
        int ret = INT_MAX;
        for(int head = left; head <= right; head++)
        {
   
            int x = dfs(left, head - 1); // 左边递归一下
            int y = dfs(head + 1, right); // 右边递归一下
            ret = min(ret, head + max(x, y)/*右边或者左边传上来的最大值*/);
        }
        memo[left][right] = ret;
        return ret;
    }
};

3、解析

在这里插入图片描述

五、矩阵中的最长递增路径

1、题目描述

leetcode链接

在这里插入图片描述

2、代码

class Solution 
{
   
public:
    int m, n;
    int dx[4] = {
   0, 0, 1, -1};
    int dy[4] = {
   1, -1, 0, 0};
    vector<vector<int>> memo;
    int longestIncreasingPath(vector<vector<int>>& matrix) 
    {
   
        int ret = 0;
        m = matrix.size();
        n = matrix[0].size();
        memo = vector<vector<int>>(m, vector<int>(n));
        for(int i = 0; i < m; i++)
        {
   
            for(int j = 0; j < n; j++)
            {
   
                ret = max(ret, dfs(matrix, i, j));
            }
        }
        return ret;
    }
    int dfs(vector<vector<int>>& matrix, int i, int j)
    {
   
        if(memo[i][j] != 0)
        {
   
            return memo[i][j];
        }
        int ret = 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[x][y] > matrix[i][j])
            {
   
                ret = max(ret, dfs(matrix, x, y) + 1);
            }
        }
        memo[i][j] = ret;
        return ret;
    }
};

3、解析

在这里插入图片描述

相关推荐

  1. 困难 Leetcode 312. 戳气球 区间dp/记忆搜索

    2024-02-23 20:38:03       9 阅读
  2. 记忆搜索

    2024-02-23 20:38:03       25 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-23 20:38:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-23 20:38:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-23 20:38:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-23 20:38:03       20 阅读

热门阅读

  1. C++之STL:unordered_map 容器

    2024-02-23 20:38:03       32 阅读
  2. LeetCode56.合并区间

    2024-02-23 20:38:03       27 阅读
  3. AutoSAR(基础入门篇)10.6-模式管理进阶

    2024-02-23 20:38:03       30 阅读
  4. LeetCode206链表相交

    2024-02-23 20:38:03       31 阅读
  5. 什么时候用ref和reactive

    2024-02-23 20:38:03       23 阅读