目录
1.最长递增子序列
题解
3.矩阵中的最长递增路径
题解
链接:300. 最长递增子序列
给你一个整数数组 nums
,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7]
是数组 [0,3,1,6,2,2,7]
的子序列。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:
输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:
输入:nums = [7,7,7,7,7,7,7]
输出:1
子序列是数组中可以不连续的的序列。
还是用记忆化搜索方式,分两步,第一步 暴搜,第二步 暴搜->记忆化搜索
暴搜
如何暴力的把最长递增子序列长度找出来
选择5然后从5递归下去,只能选择比5大的等等。(以递增为限制条件)
接下来思考一下这个递归函数如何设计
函数头 我们看我们每次都是干的什么事情
for(int i=pos+1; i
递归出口 不需要递归出口,把所有情况走完就返回了。
会超时间限制
class Solution {
public:
int lengthOfLIS(vector& nums) {
int n=nums.size();
int ret=0;
for(int i = 0; i < n; ++i)
{
ret=max(ret,dfs(nums,i));
}
return ret;
}
int dfs(vector& nums, int pos)
{
int ret=1;
//!!!!! 必须等于1,如果pos是最后一个,循环进不去,但它也是一个子序列,返回1才对.
for(int i = pos + 1; i < nums.size(); ++i)
{
if(nums[i] > nums[pos])
ret=max(ret,dfs(nums,i)+1);
}
return ret;
}
};
int ret=1;
//!!!!! 必须等于1,如果pos是最后一个,循环进不去,但它也是一个子序列,返回1才对.
暴搜->记忆化搜索
存在大量完全相同的问题,可以改成记忆化搜索
还是那三步,这里就不写了。这里备忘录用的是局部的也是可以的。
class Solution {
public:
vector memo;
int lengthOfLIS(vector& nums) {
int n=nums.size();
memo.resize(n,0);
int ret=0;
for(int i = 0; i < n; ++i)
{
ret=max(ret,dfs(nums,i));
}
return ret;
}
int dfs(vector& nums, int pos)
{
if(memo[pos]) return memo[pos];
int ret=1;
//!!!!! 必须等于1,如果pos是最后一个,循环进不去,但它也是一个子序列,返回1才对.
for(int i = pos + 1; i < nums.size(); ++i)
{
if(nums[i] > nums[pos])
ret=max(ret,dfs(nums,i)+1);
}
memo[pos]=ret;
return ret; //返回 多个选择的max ,+1是在return路径长度上 实现的
}
};
记忆化搜索->动态规划
这里动态规划代码和之前的有点不一样。
首先来一个dp表,dfs函数->状态表示:dp[i]表示以i位置为起点的最长递增子序列长度。
链接: 329. 矩阵中的最长递增路径
给定一个 m x n
整数矩阵 matrix
,找出其中 最长递增路径 的长度。
对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。
给一个mxn的矩阵,里面有很多递增序列,返回里面递增序列的最长长度。
暴搜
让找最长递增序列长度,那就暴力枚举所有递增序列从中选择最长的。
然后还要和其他位置比,选择最长的。
暴搜->记忆化搜索
从1到6搜索和从6开始的 最优搜索情况都是一样的。因此可以改成记忆化搜索。
class Solution {
public:
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int m,n;
vector> memo;
int longestIncreasingPath(vector>& matrix)
{
m=matrix.size();
n=matrix[0].size();
int count=0;
memo.resize(m,vector(n,0));
for(int i=0;i>& matrix,int i,int j)
{
if(memo[i][j]) 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=0 && ymatrix[i][j])
{
ret=max(ret,dfs(matrix,x,y)+1);
}
}
memo[i][j]=ret;
return ret;// //返回 四个方向选择的max ,+1是在return路径长度上 实现的
}
};
int ret=1; //在for前初始化
//!!!!! 必须等于1,如果pos是最后一个,循环进不去,但它也是一个子序列,返回1才对.
爆搜,满足条件 就继续搜,这很计算机~
- 多加一层搜, 就多return一个 1 的计数, return 通过Max选择 返回该点最长路径