一.377. 组合总和 Ⅳ
(1)题目描述:
给你一个由 不同 整数组成的数组 nums
,和一个目标整数 target
。请你从 nums
中找出并返回总和为 target
的元素组合的个数。题目数据保证答案符合 32 位整数范围。
(2)思路分析:
DP:类似于动态规划背包问题,每个数字可以选无数次,数字和必须为target。分析题目,我们可以发每种合法情况我们可以用dp[i][j]表示组合长度为i,数字和为j的方案数。对于任意的dp[len][target]最后一个数字可以从nums[0]到nums[n]中任意选择,则dp[len][target]应该为i取0到n,所有dp[len-1][target-nums[i]]的取和。
(3)代码演示
class Solution { // 动态规划 背包组合问题
public:
int combinationSum4(vector<int>& nums, int target) {
int size=target;
int ans=0;
vector<vector<unsigned long>> dp(size+1,vector<unsigned long>(target+1,0));
dp[0][0]=1;
for(int i=1;i<=size;i++)//组合长度
{
for(int j=target;j>=0;j--)//
{
for(auto num:nums)
{
if(j>=num)
dp[i][j]+=dp[i-1][j-num];
}
}
ans+=dp[i][target];
}
return ans;
}
};
二.124. 二叉树中的最大路径和
(1)题目描述:
二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。路径和 是路径中各节点值的总和。给你一个二叉树的根节点 root
,返回其 最大路径和 。
(2)思路分析
递归:给一个二叉树中的一个节点,其最大路径取决于自己本身和两个子节点的值大小,若两个子节点值为负,则不计入该点的最大路径和,反之如果为正,则计入该点的最大路径和。因此,我们需要一个函数max_gain()来运行得到每个点的子节点的最大贡献值,且需要一个全局变量max来维护最大路径和。
如果一个节点纳入最大路径和的取值中,那么只有两种情况:
1.其两个子节点中较大的一个加上自身数值回溯至其父节点构成最大路径和
2.其左右节点连通自身构成最大路径和
(3)代码演示
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private :
int ans;
int get_max(TreeNode* root)
{
if(!root)
return 0;
//得到最大贡献值
int l=max(get_max(root->left),0);
int r=max(get_max(root->right),0);
//节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
//更新答案,判断在该节点包含左右子树的路径和是否大于当前最大路径和
ans=max(ans,root->val+l+r);
root->val+=max(l,r);
return root->val;
}
public:
int maxPathSum(TreeNode* root) {
ans=INT_MIN;
get_max(root);
return ans;
}
};
三.329. 矩阵中的最长递增路径
(1)题目描述
给定一个 m x n
整数矩阵 matrix
,找出其中 最长递增路径 的长度。对于每个单元格,你可以往上,下,左,右四个方向移动。 你 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。
(2)思路分析
DFS+记忆化搜索:用一个数组存储先前已经计算过的点的最长递增路径,如若memo[row][column]数值存在,则直接读取先前计算过的值
(3)代码演示
class Solution {
public:
static constexpr int dirs[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int rows;
int columns;
//记忆化搜索
int longestIncreasingPath(vector<vector<int>>& matrix) {
if(matrix.size()==0||matrix[0].size()==0)
return 0;
rows=matrix.size();
columns=matrix[0].size();
auto memo=vector<vector<int>> (rows,vector<int>(columns));
int ans=0;
for(int i=0;i<rows;i++)
{
for(int j=0;j<columns;j++)
{
ans=max(ans,bfs(matrix,i,j,memo));
}
}
return ans;
}
int bfs(vector<vector<int>>&matrix,int row,int column,vector<vector<int>>&memo)
{
if(memo[row][column]!=0)
{
return memo[row][column];
}
++memo[row][column];
for(int i=0;i<4;++i)
{
int newrow=row+dirs[i][0],newcolumn=column+dirs[i][1];
if(newrow>=0&&newrow<rows&&newcolumn>=0&&newcolumn<columns&&matrix[newrow][newcolumn]>matrix[row][column])
{
memo[row][column]=max(memo[row][column],bfs(matrix,newrow,newcolumn,memo)+1);
}
}
return memo[row][column];
}
};