第一题:
原题链接:513. 找树左下角的值 - 力扣(LeetCode)
思路:用回溯的思想:
这题就是求最大深度,当遍历到第一个最大深度的时候,记录下的节点值就是最左边的元素。
参数和返回值:参数需要有一个来记录此时的节点的深度,传入下一层递归的时候进行比较,同时这个参数也是要进行回溯的,当回溯的时候深度就要-1;
终止条件:当左右节点都为空的时候同时当前深度大于最大的深度,将该节点的值记录同时更新最大深度。
单层递归逻辑:向左子树遍历的时候depth++,递归完后要depth--进行回溯。右子树同理;
代码如下:
/*** 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 findBottomLeftValue(TreeNode* root) {dfs(root, 0);return res;}
private:int res;int maxdepth = INT_MIN;void dfs(TreeNode* root, int depth){if(root -> left == nullptr && root -> right == nullptr){if(depth > maxdepth){maxdepth = depth;res = root -> val;}return;}if(root -> left){depth++;dfs(root -> left, depth);depth--;}if(root -> right){depth++;dfs(root -> right, depth);depth--;}}
};
第二题:
原题链接:112. 路径总和 - 力扣(LeetCode)
思路:
终止条件:当前遍历的节点的左右节点都为空并且节点的值等于targetSum的值则返回true;
单层递归逻辑:采用后序遍历的方式,左右中。
用bool left 和 right分别接住左右子树是否为true;
最后返回left || right.
代码如下:
/*** 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 targetSum) {if(root == nullptr) return false;if(root -> left == nullptr && root -> right == nullptr && root -> val == targetSum){return true;}bool Bleft = hasPathSum(root -> left, targetSum - root -> val);bool Bright = hasPathSum(root -> right, targetSum - root -> val);return Bleft || Bright;}
};
第三题:
原题链接:113. 路径总和 II - 力扣(LeetCode)
思路:
参数和返回值:就是题目的那个。
终止条件:当前遍历的节点的左右节点都为空并且当前节点的值等于targetSum的值,则将该这条路径添加到res数组中。
单层递归逻辑:
采用中序遍历的方式,中左右,中间节点先添加到路径,向左遍历的时候targetSum的值-=节点的值传递给下一层递归逻辑。然后回溯,将减去的值重新加到targetSum中,同时加入路径中的节点值也要弹出。同理向右子树遍历。
代码如下:
/*** 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 {};dfs(root, targetSum);return res;}
private:vector<int> path;vector<vector<int>> res;void dfs(TreeNode* root, int targetSum){path.push_back(root -> val);if(root -> left == nullptr && root -> right == nullptr && root ->val == targetSum){res.push_back(path);}if(root -> left){dfs(root -> left, targetSum - root -> val);path.pop_back();}if(root -> right){dfs(root -> right, targetSum - root -> val);path.pop_back();}}
};
第四题:
原题链接:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
思路:
首先找到根节点,就是后序遍历的最后一个元素。
找到在中序遍历中的根节点。
对中序遍历进行切割,分成左右两个子树。
根据中序遍历切割出来的子树的大小对后序遍历的数组进行切割。
最后递归处理中序和后序的左右区间。
代码如下:
class Solution {
private:TreeNode* traversal (vector<int>& inorder, vector<int>& postorder) {if (postorder.size() == 0) return NULL;// 后序遍历数组最后一个元素,就是当前的中间节点int rootValue = postorder[postorder.size() - 1];TreeNode* root = new TreeNode(rootValue);// 叶子节点if (postorder.size() == 1) return root;// 找到中序遍历的切割点int delimiterIndex;for (delimiterIndex = 0; delimiterIndex < inorder.size(); delimiterIndex++) {if (inorder[delimiterIndex] == rootValue) break;}// 切割中序数组// 左闭右开区间:[0, delimiterIndex)vector<int> leftInorder(inorder.begin(), inorder.begin() + delimiterIndex);// [delimiterIndex + 1, end)vector<int> rightInorder(inorder.begin() + delimiterIndex + 1, inorder.end() );// postorder 舍弃末尾元素postorder.resize(postorder.size() - 1);// 切割后序数组// 依然左闭右开,注意这里使用了左中序数组大小作为切割点// [0, leftInorder.size)vector<int> leftPostorder(postorder.begin(), postorder.begin() + leftInorder.size());// [leftInorder.size(), end)vector<int> rightPostorder(postorder.begin() + leftInorder.size(), postorder.end());root->left = traversal(leftInorder, leftPostorder);root->right = traversal(rightInorder, rightPostorder);return root;}
public:TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {if (inorder.size() == 0 || postorder.size() == 0) return NULL;return traversal(inorder, postorder);}
};