DFS:记忆化搜索

news/2024/7/20 21:44:24 标签: 深度优先, 算法, leetcode, 笔记, c++

​​​​​​​

一、记忆化搜索vs动态规划

. - 力扣(LeetCode)

class Solution {
public:
    //记忆化搜索
    //1、设置一个备忘录,要确保备忘录初始化的结果不能跟我们实际计算的结果相同
    //2、添加备忘录,计算的时候,如果备忘录的位置是初始值,进行修改
    //3、每次计算的时候,去备忘录瞅一瞅,找到的话,就可以不算了
    int memory[31];
    int fib(int n) 
    {
      memset(memory,-1,sizeof(memory));//利用memset进行初始化成-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];
        }
        else 
        {
            memory[n]=dfs(n-1)+dfs(n-2);
            return memory[n];
        }
    }
};

二、不同路径

class Solution {
public:
    int uniquePaths(int m, int n)
    {
        //记忆化搜索
        vector<vector<int>> memo(m+1,vector<int>(n+1,-1));//建立一个记忆数组
        return dfs(m,n,memo);//dfs去帮我搜索
    }

    int dfs(int i,int j,vector<vector<int>>&memo)
    {
       if(memo[i][j]!=-1) return memo[i][j];
       if(i==0||j==0) return 0;
       if(i==1&&j==1) return 1;
       
        memo[i][j]=dfs(i-1,j,memo)+dfs(i,j-1,memo);
        return memo[i][j];
    }
};

三、最长的递增子序列

class Solution {
public:
    //记忆化搜索
    //不用记忆化搜索的话会超时,因为本身就是一个多叉树
    int lengthOfLIS(vector<int>& nums) 
    {
       vector<int> memo(nums.size()+1,-1);
       int ret=1;
       for(int i=0;i<nums.size();++i)
       {
          ret=max(dfs(nums,i,memo),ret);
       } 
       return ret;
    }

    int dfs(vector<int>& nums,int pos,vector<int>&memo)//从pos位置开始,以pos位置做起点,往后搜索出他的最长子序列
    {
    //接下去开始从下一个位置开始找
    if(memo[pos]!=-1) return memo[pos];
    int ret=1;
    for(int i=pos+1;i<nums.size();++i)
      {
        if(nums[i]>nums[pos]) //找到了,就更新ret,然后去以下一个位置为起点接着找
        {
           ret=max(ret,dfs(nums,i,memo)+1);
        }
      }
      memo[pos]=ret;
      return memo[pos];
    }
};

四、猜数字大小II

class Solution {
public:
    int getMoneyAmount(int n) 
    {
    vector<vector<int>> memo(n+1,vector<int>(n+1));
      return dfs(1,n,memo);
    }

    int dfs(int left,int right, vector<vector<int>>&memo)
    {
        if(left>=right) return 0;
        if(memo[left][right]) return memo[left][right];//去备忘录瞅瞅 
        int ret=INT_MAX;
        for(int i=left;i<=right;++i)
        {
            int l=dfs(left,i-1,memo);//左边的最小
            int r=dfs(i+1,right,memo);//右边的最小
            ret=min(ret,max(l,r)+i);
        }
        memo[left][right]=ret;
        return memo[left][right];
    }
};

五、矩阵的最长递增路径

class Solution {
public:
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    int m,n;
    //记忆化搜索,不然会超时
    int longestIncreasingPath(vector<vector<int>>& matrix) 
    {
        int ret=1;
        m=matrix.size(),n=matrix[0].size();
        vector<vector<int>> memo(m+1,vector<int>(n+1));
       for(int i=0;i<m;++i)
       for(int j=0;j<n;++j)
         {
           ret=max(ret,dfs(matrix,i,j,memo));//以任意坐标为起点,dfs去帮我们找到最大的路径
         }
         return ret;
    }
    int dfs(vector<vector<int>>& matrix,int i,int j, vector<vector<int>>&memo)
    {
        if(memo[i][j]!=0) return memo[i][j];
       int ret=1;
       for(int k=0;k<4;++k)
       {
         int x=i+dx[k],y=j+dy[k];
         if(x>=0&&x<m&&y>=0&&y<n&&matrix[x][y]>matrix[i][j]) 
             ret=max(dfs(matrix,x,y,memo)+1,ret);
       }
       memo[i][j]=ret;//填备忘录
       return memo[i][j];
    }
};


http://www.niftyadmin.cn/n/5476322.html

相关文章

postman怎么生成随机数详细步骤及使用方式

步骤 1&#xff1a;打开 Postman 确保你已经打开了 Postman 应用程序。 步骤 2&#xff1a;创建一个请求 在 Postman 中创建一个请求&#xff0c;可以是任何类型的请求&#xff0c;例如 GET、POST 等等&#xff0c;这取决于你想要测试的接口。 步骤 3&#xff1a;打开 Pre-…

【御控物联】JavaScript JSON结构转换(15):对象To数组——转换映射方式

文章目录 一、JSON结构转换是什么&#xff1f;二、术语解释三、案例之《JSON对象 To JSON数组》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

【二分查找】Leetcode 搜索插入位置

题目解析 35. 搜索插入位置 这道题就是寻找target的目标位置&#xff0c;如果nums中包含target直接返回索引&#xff1b;如果不包含&#xff0c;需要返回target存放的合适位置 注意这道题有一个细节地方需要注意&#xff1a;如果现在target没有在nums中出现&#xff0c;并且目…

Java多线程+分治求和,太牛了

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 最近的一个面试&#xff0c;shigen简直被吊打&#xff0c;简历上写了熟悉高并发…

【刷题训练】LeetCode387.字符串中的第一个唯一字符

文章目录 题目要求解题思路代码实现 题目要求 示例 1&#xff1a; 输入: s “leetcode” 输出: 0 示例 2: 输入: s “loveleetcode” 输出: 2 示例 3: 输入: s “aabb” 输出: -1 解题思路 1.遍历一便字符串&#xff0c;并将每一个字符-‘a’得到的就是0~25的数值&…

高维解码|Redis 收紧许可证!开源软件公司如何在云时代生存?

最近&#xff0c;Redis 从开放源代码的 BSD 许可证过渡到了更加限制性的 Server Side Public License (SSPLv1)。一石激起千层浪&#xff0c;Redis 的这一举动&#xff0c;不仅分化了前 Redis 维护者&#xff0c;也再次引发业界对于“开源项目可持续性以及许可证决策对其社区的…

C++:VS dump调试(2)

之前写的&#xff1a; C&#xff1a;VS2019调试dump文件-CSDN博客 1、需要dump文件【这个一般是客户现场收集的】 2、对应的pdb文件【这个是软件编译时候生成的】 3、代码【有可能只有自己负责模块的代码&#xff0c;没有全部代码&#xff0c;但是基本调试也是只会用到自己部…

C语言——顺序表

文章目录 一、线性表二、顺序表顺序表和数组的区别顺序表的分类1.静态顺序表2.动态顺序表 三、动态顺序表的实现1.动态顺序表头文件2.动态顺序表源文件3.测试源文件 一、线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。线性表是⼀种…