每日一题:543.二叉树的直径
思路
这道题很容易看出来可以用dfs解决,但是其中有一个容易迷惑的点,就是所谓的“最长路径”并不一定经过根节点!
因此,我们需要在dfs的过程中,对每一个节点,计算其左子树的高度L以及右子树的高度R,那么以当前节点为起点的路径,经过的节点的最大值就是L+R+1,并且不断的去更新最大值。
而路径的长度就是节点数减去1,因此最后返回ans-1;
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int ans=1;
int dfs(TreeNode* root){
if(root==NULL) return 0;
//记录以左孩子为根的子树的高度
int left = dfs(root->left);
//记录以右孩子为根的子树的高度
int right = dfs(root->right);
ans=max(ans,left+right+1);
return max(left,right)+1;
}
int diameterOfBinaryTree(TreeNode* root) {
dfs(root);
return ans-1;
}
};
62.不同路径
思路
此类简化版本的迷宫问题,一上手首先想到的就是dfs,并且它的决策树也是只有两个分支,因此十分简单
但是此题用dfs会超时,所以想到使用动态规划的方法,定义一个二维动态规划数组dp,dp[i][j]表示以(i,j)作为终点时,可以选择的最大路径树,由于只能向右或者向下,显而易见,状态转移方程:
dp[i][j] = dp[i-1][j]+dp[i][j-1];
代码
递归版本(会超时):
class Solution {
public:
int ans=0;
void dfs(int m,int n,int a,int b){
if(a==m&&b==n){
ans++;
return;
}
if(a<=m&&b<=n){
dfs(m,n,a+1,b);
dfs(m,n,a,b+1);
}
else
return;
}
int uniquePaths(int m, int n) {
dfs(m,n,1,1);
return ans;
}
};
动态规划版本:
class Solution {
public:
int uniquePaths(int m, int n) {
int dp[m][n];
for(int i=0;i<n;i++)
dp[0][i]=1;
for(int i=0;i<m;i++)
dp[i][0]=1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
64.最小路径和
显而易见的一道动态规划题目,没啥可说的
代码
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m=grid.size(),n=grid[0].size();
int dp[m][n];
dp[0][0]=grid[0][0];
for(int i=1;i<n;i++){
dp[0][i]=dp[0][i-1]+grid[0][i];
}
for(int i=1;i<m;i++){
dp[i][0]=dp[i-1][0]+grid[i][0];
}
for(int i =1;i<m;i++){
for(int j=1;j<n;j++){
dp[i][j]=min(dp[i-1][j],dp[i][j-1]) + grid[i][j];
}
}
return dp[m-1][n-1];
}
};
70.爬楼梯
思路
每次爬一个或两个台阶,可以看成是决策树的分叉,写出dfs的代码并不困难,但是依然会超时,进而考虑动态规划,定义一维数组dp,dp[i]表示当高度为i时爬到顶楼的方法数,而到达i层,可以从i-2层爬两层,也可以从i-1层爬一层,所以状态转移方程:
dp[i]=dp[i-1]+dp[i-2];
代码
暴力递归(会超时)
class Solution {
public:
int ans=0;
void dfs(int n,int cur){
if(cur>n) return;
if(cur==n){
ans++;
return;
}
dfs(n,cur+1);
dfs(n,cur+2);
}
int climbStairs(int n) {
dfs(n,0);
return ans;
}
};
动态规划
class Solution {
public:
int climbStairs(int n) {
int dp[n+1];
dp[0]=dp[1]=1;
for(int i=2;i<=n;i++)
dp[i]=dp[i-2]+dp[i-1];
return dp[n];
}
};