LeetCode Path Sum 系列
题目描述
LeetCode 三道 Path Sum 的题目,给定一棵二叉树和一个路径和targetSum,分别求问:
- LeetCode 112. Path Sum 满足条件的从root到leaf的路径是否存在;
- LeetCode 113. Path Sum II 满足条件的从root到leaf的路径有哪些;
- LeetCode 437. Path Sum III 满足条件的从任意祖先节点到子孙节点的路径有几个;
解题思路
二叉树前序遍历。
从root到leaf的直接从root开始累计求和即可,采用回溯方式,进分支后累加本节点value,退出分支前减去本节点value;
任意祖先到子孙结点路径,需要借助从root到当前结点的路径来回溯,到达任意结点后首先判断到root的路径是否符合要求,然后检查这条路径上其他起点的路径是否满足要求;
参考代码
Path Sum
非递归,使用栈作为辅助。
/*
* @lc app=leetcode id=112 lang=cpp
*
* [112] Path Sum
*/
// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
// if(root == nullptr) return (sum == 0);
if(root == nullptr) return false;
// BFS或者DFS都可以,这里用DFS可以更快结束
stack<pair<TreeNode*, int>> stk;
stk.push({root, root->val});
while(!stk.empty()) {
auto p = stk.top();
stk.pop();
TreeNode* ptr = p.first;
int psum = p.second;
if(psum == sum && ptr->left == nullptr && ptr->right == nullptr) return true;
if(ptr->right) stk.push({ptr->right, psum + ptr->right->val});
if(ptr->left) stk.push({ptr->left, psum + ptr->left->val});
}
return false;
}
};
// @lc code=end
Path Sum II
回溯,递归解法。
/*
* @lc app=leetcode id=113 lang=cpp
*
* [113] Path Sum II
*/
// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
if (root == nullptr) return {};
vector<vector<int>> res;
vector<int> path;
find(res, path, root, targetSum);
return res;
}
void find(vector<vector<int>>& res, vector<int>& path, TreeNode* root, int targetSum) {
assert(root != nullptr);
path.push_back(root->val);
targetSum -= root->val;
if (root->left == nullptr && root->right == nullptr) {
// leaf
if (targetSum == 0) {
res.push_back(path);
}
// path.clear();
// return; // pop_back leaf at end
}
if (root->left) find(res, path, root->left, targetSum);
if (root->right) find(res, path, root->right, targetSum);
path.pop_back();
targetSum += root->val;
} // AC
};
// @lc code=end
Path Sum III
回溯,递归解法。
/*
* @lc app=leetcode id=437 lang=cpp
*
* [437] Path Sum III
*/
// @lc code=start
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int pathSum(TreeNode* root, int sum) {
if (root == nullptr) return {};
int res = 0;
vector<int> path;
find(res, path, root, sum);
return res;
}
void find(int& res, vector<int>& path, TreeNode* root, int targetSum) {
assert(root != nullptr);
path.push_back(root->val);
targetSum -= root->val;
if (targetSum == 0) {
res++;
} // path from root to this node
int tsum = targetSum;
for (int i=0; i<path.size()-1; i++) {
if ((tsum += path[i]) == 0) {
res++;
} // path from ancestors to this node
}
if (root->left) find(res, path, root->left, targetSum);
if (root->right) find(res, path, root->right, targetSum);
path.pop_back();
targetSum += root->val;
} // AC
};
// @lc code=end