[LeetCode 112 113] - 路径和I & II (Path Sum I & II)

问题

给出一棵二叉树及一个和值,检查该树是否存在一条根到叶子的路径,该路径经过的所有节点值的和等于给出的和值。

例如,

给出以下二叉树及和值22:

         5
        / \
       4  8
      /   / \
    11 13 4
    / \        \
  7   2        1

函数返回true,因为存在一条根到叶子的路径5->4->11->2,其路径和为22。

 

初始思路

鉴于题目要求找到一条路径和符合要求即可,选择层次遍历二叉树是一种比较合适的选择-保证了我们首先找到的是最短的路径从而节省了时间。另外由于没有禁止修改原二叉树的值,我们在处理过程中可以把每个点的值修改为到达这点时的路径和,方便比较。至于层次遍历的方法,大家应该已经很熟悉了,使用116,117中的双vector法即可:

 1 class Solution {
 2     public:
 3         bool hasPathSum(TreeNode *root, int sum)
 4         {
 5             if(!root)
 6             {
 7                 return false;
 8             }
 9             
10             treeLevel_[0].clear();
11             treeLevel_[1].clear();
12             
13             bool flag = false;
14             treeLevel_[0].push_back(root);
15             
16             while(!treeLevel_[flag].empty())
17             {
18                 for(auto iter = treeLevel_[flag].begin(); iter != treeLevel_[flag].end(); ++iter)
19                 {
20                     if(!(*iter)->left && !(*iter)->right)
21                     {
22                         if((*iter)->val == sum)
23                         {
24                             return true;
25                         }
26                     }
27                     
28                     if((*iter)->left)
29                     {
30                         (*iter)->left->val += (*iter)->val;
31                         
32                         treeLevel_[!flag].push_back((*iter)->left);
33                     }
34                     
35                     if((*iter)->right)
36                     {
37                         (*iter)->right->val += (*iter)->val;
38 
39                         
40                         treeLevel_[!flag].push_back((*iter)->right);
41                     }
42                 }
43                 
44                 treeLevel_[flag].clear();
45                 
46                 flag = !flag;
47             }
48             
49             return false;
50         }
51         
52     private:
53         
54         std::vector<TreeNode*> treeLevel_[2];
55     };
hasPathSum

提交后Judge Small和Judge Large双双通过。

 

扩展问题

给出一棵二叉树及一个和值,找出符合条件的所有根到叶子的路径,这些路径经过的所有节点值的和等于给出的和值。

例如,

给出以下二叉树及和值22:

         5 
        / \
       4  8
      /   / \
    11 13 4
    / \     / \
  7   2  5    1

返回

[
  [5,4,11,2],
  [5,8,4,5]
]

 

扩展问题初始思路

题目要求找出所有符合条件的路径,意味着不管用什么方法都必须把所有节点遍历一遍。如果还是使用前面的层次遍历,因为是广度优先遍历,需要同时跟踪多条路径的和,直到走到叶子节点。因此在这里我们尝试使用普通的递归中序遍历,由于这是一种深度优先遍历,通过进栈及出栈操作,可以做到一次只需跟踪一条路径即可:

 1 class Solution113 {
 2     public:
 3         std::vector<std::vector<int> > pathSum(TreeNode *root, int sum)
 4         {
 5             result_.clear();
 6             if(!root)
 7             {
 8                 return result_;
 9             }
10             
11             currentPath_.clear();
12             currentPath_.push_back(root->val);
13             sum_ = sum;
14             currentSum_ = root->val;
15             
16             FindPathSum(root);
17             
18             return result_;
19         }
20         
21     private:
22         
23         void FindPathSum(TreeNode *node)
24         {
25             if(!node->left && !node->right)
26             {
27                 if(currentSum_ == sum_)
28                 {
29                     result_.push_back(currentPath_);
30                 }
31                 
32                 return;
33             }
34             
35             if(node->left)
36             {
37                 currentSum_ += node->left->val;
38                 currentPath_.push_back(node->left->val);
39                 FindPathSum(node->left);
40                 currentSum_ -= node->left->val;
41                 currentPath_.pop_back();
42             }
43             
44             if(node->right)
45             {
46                 currentSum_ += node->right->val;
47                 currentPath_.push_back(node->right->val);
48                 FindPathSum(node->right);
49                 currentSum_ -= node->right->val;
50                 currentPath_.pop_back();
51             }
52             
53         }
54         
55         std::vector<std::vector<int> > result_;
56         std::vector<int> currentPath_;
57         int sum_;
58         int currentSum_;
59         
60     };
pathSum

提交后同样Judge Small和Judge Large双双通过。

 

posted @ 2013-07-25 22:51  Shawnone  阅读(290)  评论(0编辑  收藏  举报