Problem Statement:
Path sum i
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example: Given the below binary tree andsum = 22
,
5 / 4 8 / / 11 13 4 / 7 2 1
return true, as there exist a root-to-leaf path 5->4->11->2
which sum is 22.
Solution one(traverse version):
This is the traverse version.
For each node:
- Check if it is NULL, yes, return false
- If it is not NULL
- Update the sum, sum = sum - node->val
if current node is leaf node( node->left == NULL && node->right == NULL) and the new sum is equal to 0, we find the answer, return true.
Not leaf node, node left child is not empty and there is a path in left child or right child is not empty and there is a path in right child, return true.
Otherwise, return false.
1 class Solution { 2 public: 3 bool hasPathSum(TreeNode* root, int sum) { 4 if(root == NULL){ 5 return false; 6 } 7 sum -= root->val; 8 if(sum == 0 && root->left == NULL && root->right == NULL){ 9 return true; 10 } 11 if((root->left && hasPathSum(root->left, sum)) || (root->right && hasPathSum(root->right, sum))){ 12 return true; 13 } 14 return false; 15 } 16 };
Solution two(divide && conquer):
Divide the question to left and right, return true if there is one true between left and right.
otherwise, return false
1 class Solution { 2 public: 3 bool hasPathSum(TreeNode* root, int sum) { 4 if(root == NULL){ 5 return false; 6 } 7 8 sum -= root->val; 9 if(root->left == NULL && root->right == NULL && sum == 0){ 10 return true; 11 } 12 13 // divide 14 bool leftHasPathSum = hasPathSum(root->left, sum); 15 bool rightHasPathSum = hasPathSum(root->right, sum); 16 17 // conquer 18 if(leftHasPathSum || rightHasPathSum){ 19 return true; 20 } 21 return false; 22 } 23 };
Solution three(while loop and preorder to solve the problem):
Since we need find a path from root to leaf, the sum is equal to a given value. We traverse the tree from root by preorder: root->left->right.
Current node is not empty:
- if it is a leaf and sum is already equal to 0, we find a path, return true.
- else go to the left child of current node.
Current node is empty:
- Pop the top element from stack and pop the sum value from value stack, this value corresponding to the sum from root to current node.
Until the stack is empty, we return false.
1 class Solution { 2 public: 3 bool hasPathSum(TreeNode* root, int sum) { 4 if(root == NULL){ 5 return false; 6 } 7 stack<TreeNode*> node_stack; 8 stack<int> val_stack; 9 node_stack.push(root); 10 val_stack.push(root->val); 11 TreeNode* cur_node; 12 int cur_val = 0; 13 14 while(!node_stack.empty()){ 15 if(root){ 16 cur_val += root->val; 17 node_stack.push(root); 18 val_stack.push(cur_val); 19 if(root->left == NULL && root->right == NULL && cur_val == sum){ 20 return true; 21 } else { 22 root = root->left; 23 } 24 } else { 25 root = node_stack.top(); 26 node_stack.pop(); 27 root = root->right; 28 cur_val = val_stack.top(); 29 val_stack.pop(); 30 } 31 } 32 return false; 33 } 34 };
NOTES:
The important for non-traverse version is the value stack, we need keep a value stack. Each time, we need push the sum value to stack when we push a node to stack.
we can not keep a variable to store the sum for current node. That does not work.
I know how to solve this problem, however, spend much time for configure out that to keep a stack.