LeetCode 113. 路径总和 II
题意:给出一棵二叉树,给定一个目标数值targetSum,输出所有从根节点到叶子节点路径数值和与targetSum相等的路径。
思路:遍历所有路径,可以使用深度优先搜索,搜索完一条路径再到下一条路径;使用容器记录当前走的节点和容器内的数值和,当当前节点是叶子节点就判断容器内的数值和是否等于targetSum,如果是就存储容器内的节点。
例子:使用题目给出的数据,targetSum是22;
定义一个容器(存储路径)和一个整形(计算总和),从根节点开始遍历整棵二叉树,图下是完成了第一条路径,判断条件是子节点左右子节点是空,nSum跟targetSum不相等,这条路径不成立;
再进行下一条路径,返回上一节点之前需要将nSum减去当前节点和容器弹出对应节点。图下是第二条路径,nSum等于targetSum,路径成立,将容器内的数值存储下来;
进行下一条路径,流程也跟上述一样,最后到叶子节点,判断nSum与targetSum是否相等,不行等路径不成立;
进行下一条路径,nSum与targetSum相等,将容器内数值存储下来;
下一条路径,nSum与targetSum不行等;
搜索完毕。
主要流程如上述所示。
代码实现如下:
class Solution {
public:
void DFS(TreeNode* root, vector< vector<int> >& res,
vector<int> tmpres, int targetSum, int& nSum) {
if(root == nullptr) {
return ;
}
nSum += root->val;
tmpres.push_back(root->val);
if(nSum == targetSum && root->left == nullptr &&
root->right == nullptr) {
res.push_back(tmpres);
tmpres.pop_back();
nSum -= root->val;
return ;
}
DFS(root->left, res, tmpres, targetSum, nSum);
DFS(root->right, res, tmpres, targetSum, nSum);
nSum -= root->val;
tmpres.pop_back();
}
vector< vector<int> > pathSum(TreeNode* root,
int targetSum) {
vector< vector<int> > result;
result.clear();
vector<int> path;
int nSum = 0;
DFS(root, result, path, targetSum, nSum);
return result;
}
};
LeetCode 437. 路径总和 III
题意:这题跟上一题也是找路径nSum跟targetSum相等的路径,但是可以不从根节点开始和结束不用是叶子节点,不过路径是要连续向下的。
思路:跟上一题一样,先找出完整的一条路径,然后再进行路径的数值遍历,计算子路径和是否跟targetSum相等,如果到了另外一条完整路径,其中的子路径已经遍历过的话,我们就不进行计算,重复上述流程,直到遍历完整棵二叉树。
例子:使用题目给出的数据,targetSum是8;
定义一个容器(存储路径)、一个整形nSum(计算总和)、另一个整形nTag(已经遍历过路径的前n个子节点)。
图下为第一条遍历到的路径,当前节点左右子节点都是空,找到一条完整的路径,就进行子路径的遍历,计算出nSum,判断是否有targetSum相等的子路径;
下一条路径,然后nTag标记成3,因为前三个数已经是有遍历过的,不重复进行计算,计算剩下的子路径
下一条路径,nTag标记成2;
下一条路径,nTag标记成1;
搜索完毕,主要流程如上述所示。
代码实现如下:
class Solution {
public:
void DFS(TreeNode* root, vector<int> path, int targetSum,
int& nResult, int& nTag){
if(root == nullptr) {
return ;
}
path.push_back(root->val);
if(root->left == nullptr && root->right == nullptr) {
for(int i=0; i<path.size(); i++) {
int nSum = 0;
for(int j=i; j<nTag; j++) {
nSum += path[j];
}
int k = nTag;
if(i > nTag) k = i;
for(int j=k; j<path.size(); j++) {
nSum += path[j];
if(nSum == targetSum) {
nResult++;
}
}
}
nTag = path.size();
path.pop_back();
nTag--;
return ;
}
if(root->left != nullptr) {
DFS(root->left, path, targetSum, nResult, nTag);
}
if(root->right != nullptr) {
DFS(root->right, path, targetSum, nResult, nTag);
}
path.pop_back();
nTag--;
}
int pathSum(TreeNode* root, int targetSum) {
int nResult = 0;
vector<int> path;
int nTag = 0;
DFS(root, path, targetSum, nResult, nTag);
return nResult;
}
};