方法一:递归DFS
- 使用DFS递归加回溯的方法。
图解过程如下:
代码如下:
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
//DFS+回溯
dfs(root,expectNumber);
return ans;
}
void dfs(TreeNode* root,int expectNumber){
if(root==nullptr)
return;
expectNumber-=root->val;
//DFS,进入
path.push_back(root->val);
//满足条件的路径,值相等且当前为叶子节点。
if(expectNumber==0&&root->left==nullptr&&root->right==nullptr){
ans.push_back(path);
}
dfs(root->left,expectNumber);
dfs(root->right,expectNumber);
//回溯,恢复path。
path.pop_back();
}
};复杂度分析:
时间复杂度:O(n^2),取决于二叉树的形状。举例如下:
- 假设n/2的节点为链表状,n/2的节点为完全二叉树,每一个路径都是符合条件的,那么符合条件的路径数为n/4。每条路径上的节点数为(n/2+log(n+1/2))个,相乘时间复杂度为O(n^2)。
空间复杂度:O(n)。递归栈空间O(n)。
方法二:非递归DFS
- 相比于递归DFS,非递归的代码会相对复杂度更高,因为需要栈来存储节点和节点路径。
- 还有BFS的方法,相比于DFS,它会存储很多暂时用不到的数据,表现的效果不如DFS。
class Solution {
public:
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
vector<vector<int>> ans;
vector<int> path;
if(root==nullptr)
return ans;
//s是存储节点的栈,ps是存储对应节点路径的栈。
stack<TreeNode*> s;
stack<vector<int>> ps;
s.push(root);
path.push_back(root->val);
ps.push(path);
while(!s.empty()){
TreeNode* cur=s.top();
s.pop();
vector<int> tmp=ps.top();
ps.pop();
//判断是否为所求路径
if(cur->val==expectNumber&&cur->left==nullptr&&cur->right==nullptr)
ans.push_back(tmp);
//左右子节点是否存在,若存在,更新s和ps
if(cur->right){
vector<int> rtmp;
for(int x:tmp)
rtmp.push_back(x);
rtmp.push_back(cur->right->val);
ps.push(rtmp);
cur->right->val+=cur->val;
s.push(cur->right);
}
if(cur->left){
tmp.push_back(cur->left->val);
ps.push(tmp);
cur->left->val+=cur->val;
s.push(cur->left);
}
}
return ans;
}
};复杂度分析:
时间复杂度:O(n^2),同上
空间复杂度:O(n),用了一个存储路径和节点的栈。



京公网安备 11010502036488号