题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
首先想到了递归的方法,针对左右子树不断进行节点和的判断。同时要有变量来存储路径和节点和,“后入先出”可以选择栈或者vector,节点和只需要一个整型变量用来存储即可,
因为路径是从根节点出发到叶节点,也就是说路径总是以根节点为起始点,因此我们需要遍历根节点。在树的前序、中序、后序3种遍历方式中,只有前序遍历是首先访问根节点的。从二叉树节点的定义看出,本题的二叉树节点中没有指向父节点的指针,所以需要把经过的路径上的节点保存下来。每访问一个节点,我们都把当前节点保存到路径中。每次当从子节点回到父节点的时候,我们都需要在路径上删除子节点。
按照我之前的想法,只要当前节点的路径使和满足要求,就可以停止往当前节点的子节点遍历,但讨论区看到一个网友的话觉得很有道理,题目并没有说明节点的正负,如果有节点是负的,后面子节点就还要继续遍历下去。
方法一:sum= sum- 当前节点->val 递归判断下一个节点值与sum是否相等(这种方法参考讨论区的大神,一般人的想法可能都是将节点值想加,看获得的sum是否与指定的数值相同。)4ms 486K
class Solution { public: //全局变量 vector<vector<int>> res; vector<int> path; vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { find(root,expectNumber); return res; } void find(TreeNode* root,int sum){ if(root == NULL){ return; } path.push_back(root->val); if(!root->left && !root->right && sum == root->val){ res.push_back(path); } else{ if(root->left){ find(root->left,sum - root->val); } if(root->right){ find(root->right,sum - root->val); } } path.pop_back(); } };
方法二:同上述方法的思路一样,但没有另外写子函数,都在FindPath中完成.3ms,616K
class Solution { public: vector<vector<int>> res; vector<int> path; vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { if(root == NULL){ return res; } path.push_back(root->val); if((expectNumber-root->val) == 0 && root->left == NULL && root->right == NULL){ res.push_back(path); } else{ if(root->left) FindPath(root->left,expectNumber-root->val); if(root->right) FindPath(root->right,expectNumber-root->val); } if(!path.empty()){ path.pop_back(); } return res; } };