113. Path Sum II
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
Given the below binary tree and
sum = 22
,
5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1
return
[ [5,4,11,2], [5,8,4,5] ]
Solution: 直接递归求解。
Code(1): return的方式传递vector。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> ans;
if(root==NULL) return ans;
if(root->left==NULL && root->right==NULL){
if(root->val==sum){
vector<int> v;
v.push_back(root->val);
ans.push_back(v);
}
return ans;
}
vector<vector<int>> vleft = pathSum(root->left, sum-root->val);
vector<vector<int>> vright = pathSum(root->right, sum-root->val);
ans.insert(ans.end(), vleft.begin(), vleft.end());
ans.insert(ans.end(), vright.begin(), vright.end());
for(int i=0; i<ans.size(); i++){
ans[i].insert(ans[i].begin(), root->val);
}
return ans;
}
};
Code(2): 使用引用(&)传递vecotr。注意,使用引用传递ans时,要注意使用一个数组cur来记录到从根节点到前节点路径,而不能将数据直接记录到ans中,因为是使用了深搜,因此在搜索右子树时,左子树的结果已经存入ans数组,这会导致结果出错。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> ans;
vector<int> cur;
pathSum(root, sum, cur, ans);
return ans;
}
private:
void pathSum(TreeNode* root, int sum, vector<int>& cur, vector<vector<int>>& ans){
if(root==NULL) return;
cur.push_back(root->val);
if(root->left==NULL && root->right==NULL){
if(root->val==sum){
ans.push_back(cur);
}
}else{
pathSum(root->left, sum-root->val, cur, ans);
pathSum(root->right, sum-root->val, cur, ans);
}
cur.pop_back();
}
};
53. Maximum Subarray
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [-2,1,-3,4,-1,2,1,-5,4]
,
the contiguous subarray [4,-1,2,1]
has the largest sum = 6
.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
Solution(1): 动态规划,解释摘自《leetcode详解》。
Code:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int f = nums[0];
int maxVal = f;
for(int i=1; i<nums.size(); i++){
f = max(nums[i], f+nums[i]);
if(f>maxVal) maxVal = f;
}
return maxVal;
}
};
Solution(2): 处理后枚举,连续子序列的和等于两个前缀和之差,复杂度O(n^2)。将这种算法稍作处理后可得到O(n)的解,Code部分给出O(n)的写法。
Code:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int MIN = 0;
int MAX = nums[0];
int total = nums[0];
for(int i=1; i<nums.size(); i++){
MAX = max(MAX, nums[i]);
MIN = min(MIN, total);
MAX = max(MAX, nums[i]+total-MIN);
total += nums[i];
}
return MAX;
}
};
Solution(3): 分治法,将数组分成两段,分别求最大,然后归并(即比较左半段、右半段、和中间节点向两边遍历得到的最大和,取这三个数的最大值)。时间复杂度为O(nlogn)。
Code:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
return maxSubArray(nums.begin(), nums.end());
}
private:
int maxSubArray(vector<int>::iterator begin, vector<int>::iterator end){
if(begin==end) return INT_MIN;
vector<int>::iterator mid = begin + (end-begin)/2;
int maxSide = maxSubArray(begin, mid);
maxSide = max(maxSubArray(mid+1, end),maxSide);
int maxMid = *mid;
int cur = *mid;
for(auto i=mid-1; i-begin>=0; i--){
cur += *i;
if(cur>maxMid) maxMid = cur;
}
cur = maxMid;
for(auto i=mid+1; i!=end; i++){
cur += *i;
if(cur>maxMid) maxMid = cur;
}
return max(maxMid, maxSide);
}
};
124. Binary Tree Maximum Path Sum
Given a binary tree, find the maximum path sum.
For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.
For example:
Given the below binary tree,
1 / \ 2 3
Return 6
.
Solution: 最大连续子序列和(53)的变体题,同样可以使用动态规划的思想。假设f[x]为包含根节点(x)的最大连续子序列和(注意,只返回一个方向上的和即left->root或者right->root),则可得递推公式f[root] =f[root]+max(f[root->left],0)+max(f[root->right,0),得到递推公式后,递归求解即可。
Code:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxPathSum(TreeNode* root) {
maxSumWithRoot(root);
return maxSum;
}
private:
int maxSum = INT_MIN;
int maxSumWithRoot(TreeNode* root){
//返回值是从root出发(包括root)到叶子节点的路径上最大的和(root->...)
if(root==NULL) return INT_MIN;
int maxval = root->val;
int l = maxSumWithRoot(root->left);
int r = maxSumWithRoot(root->right);
if(l>0) maxval += l;
if(r>0) maxval += r;
maxSum = max(maxSum, maxval);
return max(r,l)>0 ? root->val+max(r,l) : root->val;
}
};