算法训练营 第十八天
day05~
513.找树左下角的值
这道题的难度在于,他需要回传高度和结点值两个信息,一种方法是递归函数的返回值设置为vector<int>
,将高度信息和节点值信息保存到数组里,另一种方法是,把高度信息以引用的形式当作形参传入递归函数
方法一:将两个信息作为返回值传递
class Solution {
public:
vector<double> digui(TreeNode* root) {
if (root == nullptr)
return { MINNUM,0 };
if(root->left==nullptr&&root->right==nullptr)
return { (double)root->val,1 };
auto leftInfo = digui(root->left);
auto rightInfo = digui(root->right);
if (leftInfo[1] >= rightInfo[1])
return{ leftInfo[0], leftInfo[1] + 1 };
return {rightInfo[0], rightInfo[1] + 1};
}
int findBottomLeftValue(TreeNode* root) {
if(root->left==nullptr&&root->right==nullptr)
return root->val;
return digui(root)[0];
}
private:
double MINNUM = -pow(2,31)-1;
};
注:用double的返回值是因为这道题的val范围是-2^31,超过了int的取值范围
方法二:将高度信息作为形参传递
class Solution {
public:
int maxDepth = INT_MIN;
int result;
void traversal(TreeNode* root, int depth) {
if (root->left == NULL && root->right == NULL) {
if (depth > maxDepth) {
maxDepth = depth;
result = root->val;
}
return;
}
if (root->left) {
depth++;
traversal(root->left, depth);
depth--; // 回溯
}
if (root->right) {
depth++;
traversal(root->right, depth);
depth--; // 回溯
}
return;
}
int findBottomLeftValue(TreeNode* root) {
traversal(root, 0);
return result;
}
};
112.路径总和
这道题和第257道题很像,就是求二叉树的所有路径,然后判断是否有路径总和和目标和相同的路径。一旦找到路径则不用再进行其他操作了,直接返回true。
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if (root == nullptr)
return false;
pathSum += root->val;
if (root->left == nullptr && root->right == nullptr && pathSum == targetSum) {
return true;
}
if (root->left) {
if (hasPathSum(root->left, targetSum))
return true;
pathSum -= root->left->val;
}
if (root->right) {
if (hasPathSum(root->right, targetSum)
return true;
pathSum -= root->right->val;
}
return false;
}
private:
int pathSum = 0;
};
113. 路径总和II
这道题和112一样,只不过需要用vector<int>path
记录路径
class Solution {
public:
void hasPathSum(TreeNode* root, int targetSum, vector<int>& path,vector<vector<int>>& res) {
if (root == nullptr)
return ;
if (root->left == nullptr && root->right == nullptr && 0 == targetSum) {
res.push_back(path);
return ;
}
if (root->left) {
path.push_back(root->left->val);
hasPathSum(root->left, targetSum - root->left->val, path, res);
path.pop_back();
}
if (root->right) {
path.push_back(root->right->val);
hasPathSum(root->right, targetSum- root->right->val,path,res);
path.pop_back();
}
return ;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
vector<vector<int>> res;
vector<int> path;
if (root == nullptr)
return res;
path.push_back(root->val);
hasPathSum(root, targetSum-root->val, path, res);
return res;
}
};
106.从中序与后序遍历序列构造二叉树
这道题重点是想清楚怎么分割中序和后序序列,以及递归的传入值该怎么传。
class Solution {
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if (postorder.size() == 0)
return nullptr;
if (postorder.size() == 1)
return new TreeNode(postorder[0], nullptr, nullptr);
TreeNode* root = new TreeNode(postorder.back());
int index = 0;
for (; index < inorder.size(); index++) {
if (inorder[index] == postorder.back())
break;
}
vector<int> leftInorder(inorder.begin(), inorder.begin() + index);
vector<int> rightInorder(inorder.begin() + index + 1, inorder.end());
vector<int> leftPostorder(postorder.begin(), postorder.begin() + index);
vector<int> rightPostorder(postorder.begin() + index, postorder.end() - 1);
root->left = buildTree(leftInorder, leftPostorder);
root->right = buildTree(rightInorder, rightPostorder);
return root;
}
};
105. 从前序与中序遍历序列构造二叉树
这道题的思路和106相同
class Solution {
public:
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if (preorder.size() == 0)
return nullptr;
if (preorder.size() == 1)
return new TreeNode(preorder[0]);
int index = 0;
for (; index < inorder.size(); index++) {
if (inorder[index] == preorder[0])
break;
}
vector<int> leftPreorder(preorder.begin() + 1, preorder.begin() + 1 + index);
vector<int> rightPreorder(preorder.begin() + 1 + index, preorder.end());
vector<int> leftInorder(inorder.begin(), inorder.begin() + index);
vector<int> rightInorder(inorder.begin() + index + 1, inorder.end());
TreeNode* root = new TreeNode(preorder[0]);
root->left = buildTree(leftPreorder, leftInorder);
root->right = buildTree(rightPreorder, rightInorder);
return root;
}
};