一、題目說明
題目437. Path Sum III,給定一個二叉樹和整數sum,計算路徑和是sum的數量,其中路徑只能是從父節點向下的。難度是Easy!
二、我的解答
這個題目絕對不是Easy!最直觀的想法,先判斷根節點是否有路徑,然後判斷左子樹,右子樹是否有路徑。
class Solution{
public:
int pathSum(TreeNode* root,int sum){
if(root==NULL) return 0;
return dfs(root,sum) + pathSum(root->left,sum) + pathSum(root->right,sum);
}
int dfs(TreeNode* root,int sum){
//以root爲起點,任意節點可作爲結束和爲sum的個數
if(root==NULL) return 0;
sum = sum - root->val;
int cur = sum==0? 1: 0;
return cur + dfs(root->left,sum) + dfs(root->right,sum);
}
};
性能如下:
Runtime: 24 ms, faster than 49.38% of C++ online submissions for Minimum Path Sum.
Memory Usage: 14.6 MB, less than 50.00% of C++ online submissions for Minimum Path Sum.
三、優化措施
網上找了一個dp算法:這個題目類似數組求連續和,將遞歸算法消除一層遞歸!
class Solution{
public:
// dp solution
int pathSum(TreeNode* root,int sum){
if(root==NULL) return 0;
sums.resize(maxDepth(root)+1,0);
dfs(root,1,sum);
return count;
}
int maxDepth(TreeNode* root){
if(root==NULL) return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
void dfs(TreeNode* root,int level,int sum){
if(root==NULL) return;
sums[level] = sums[level-1] + root->val;
for(int i=0;i<level;i++){
if(sums[level]-sums[i]==sum) count++;
}
dfs(root->left,level+1,sum);
dfs(root->right,level+1,sum);
}
private:
int count = 0;
vector<int> sums;
};
性能如下:
Runtime: 20 ms, faster than 77.01% of C++ online submissions for Path Sum III.
Memory Usage: 14.6 MB, less than 100.00% of C++ online submissions for Path Sum III.