【剑指offer】14.二叉树中和为某一值的路径(一)
总目录:
1.问题描述
给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
例如:
给出如下的二叉树, sum=22 sum=22,
给出如下的二叉树, sum=22 sum=22,
返回true,因为存在一条路径 5→4→11→25→4→11→2的节点值之和为 22
数据范围:
1.树上的节点数满足 0≤n≤10000
2.每 个节点的值都满足 ∣val∣≤1000
要求:空间复杂度 O(n),时间复杂度 O(n)
进阶:空间复杂度 O(树的高度),时间复杂度 O(n)
2.问题分析
1递归法,递归到叶节点为止,检查一路下来值和
2用栈,深度搜索,栈顶是从根节点一路加下来的和,到了某个叶子节点处如果不符合要求则返回false,到了非叶子节点处要将累加到本节点的和分别加上子节点的值并压栈。
3.代码实例
递归
1 /** 2 * struct TreeNode { 3 * int val; 4 * struct TreeNode *left; 5 * struct TreeNode *right; 6 * }; 7 */ 8 9 class Solution { 10 public: 11 /** 12 * 13 * @param root TreeNode类 14 * @param sum int整型 15 * @return bool布尔型 16 */ 17 bool AddToEndRecurve(TreeNode* root, const int tgtSum, int curSum) { 18 //中止条件,到叶子节点时才判断 19 if (!root) { 20 return false; 21 } 22 curSum += root->val; 23 if (root->left == NULL && root->right == NULL) { 24 return curSum == tgtSum; 25 } 26 27 //递归调用 28 auto isLeft = AddToEndRecurve(root->left, tgtSum, curSum); 29 auto isRight = AddToEndRecurve(root->right, tgtSum, curSum); 30 return isLeft || isRight; 31 } 32 33 bool hasPathSum(TreeNode* root, int sum) { 34 int curSum = 0; 35 return AddToEndRecurve(root, sum, curSum); 36 } 37 };
栈,深度优先搜索
1 class Solution { 2 public: 3 bool hasPathSum(TreeNode* root, int sum) { 4 //空节点找不到路径 5 if(root == NULL) 6 return false; 7 //栈辅助深度优先遍历,并记录到相应节点的路径和 8 stack<pair<TreeNode*, int> > s; 9 //根节点入栈 10 s.push({root, root->val}); 11 while(!s.empty()){ 12 auto temp = s.top(); 13 s.pop(); 14 //叶子节点且路径和等于sum 15 if(temp.first->left == NULL && temp.first->right == NULL && temp.second == sum) 16 return true; 17 //左节点入栈 18 if(temp.first->left != NULL) 19 s.push({temp.first->left, temp.second + temp.first->left->val}); 20 //右节点入栈 21 if(temp.first->right != NULL) 22 s.push({temp.first->right, temp.second + temp.first->right->val}); 23 } 24 return false; 25 } 26 };