513.找树左下角的值
类型: #二叉树
难度: #中等
题目:给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。假设二叉树中至少有一个节点。
思路:找最底层左节点的值,就要找深度最大的左节点的值。全局变量最大长度和结果,然后前序遍历(但不需要收集中节点)递归完成。
实现:
cpp:
/**
* 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 maxD = INT_MIN;
int result = 0;
void traversal(TreeNode* root, int depth){
if (root->left == NULL && root->right == NULL){
if(depth > maxD){
maxD = 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;
}
};
go:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var maxD int
var result int
func dfs(root *TreeNode, d int){
if root == nil{
return
}
if root.Left == nil && root.Right == nil && d > maxD {
maxD = d
result = root.Val
}
if root.Left != nil {
d++
dfs(root.Left, d)
d--
}
if root.Right != nil {
d++
dfs(root.Right, d)
d--
}
}
func findBottomLeftValue(root *TreeNode) int {
maxD, result = 0, 0
dfs(root, 1)
return result
}
112. 路径总和
类型: #二叉树
难度: #简单
题目:给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
思路:用 targetSum 去减当前节点的值,如果是叶子节点同时 sum 为 0,则返回 true
实现:
cpp:
/**
* 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) return false;
if(!root->left && !root->right && targetSum == root->val) return true;
return hasPathSum(root->left, targetSum - root->val) || hasPathSum(root->right, targetSum - root->val);
}
};
go:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func hasPathSum(root *TreeNode, targetSum int) bool {
if root == nil{
return false
}
if root.Left == nil && root.Right == nil && root.Val == targetSum{
return true
}
return hasPathSum(root.Left, targetSum-root.Val) || hasPathSum(root.Right, targetSum-root.Val)
}
113.路径总和ii
类型: #二叉树
难度: #中等
题目:给你二叉树的根节点 root 和一个整数目标和 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>> res;
vector<int> path;
void traversal (TreeNode* root, int sum){
if(!root->left && !root->right && sum==0){
res.push_back(path);
return;
}
if(!root->left && !root->right) return;
if(root->left){
path.push_back(root->left->val);
sum -= root->left->val;
traversal(root->left, sum);
sum += root->left->val;
path.pop_back();
}
if(root->right){
path.push_back(root->right->val);
sum -= root->right->val;
traversal(root->right, sum);
sum += root->right->val;
path.pop_back();
}
return;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
path.clear();
res.clear();
if(root == NULL) return res;
path.push_back(root->val);
traversal(root, targetSum-root->val);
return res;
}
};
go:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var res [][]int
var path []int
func traversal(root *TreeNode, sum int) {
if root == nil {
return
}
path = append(path, root.Val)
defer func() { path = path[:len(path)-1] }()
if root.Left == nil && root.Right == nil && sum == root.Val {
temp := make([]int, len(path))
copy(temp, path)
res = append(res, temp)
return
}
traversal(root.Left, sum-root.Val)
traversal(root.Right, sum-root.Val)
}
func pathSum(root *TreeNode, targetSum int) [][]int {
res = make([][]int, 0)
path = make([]int, 0)
traversal(root, targetSum)
return res
}
106.从中序与后序遍历序列构造二叉树
类型: #二叉树
难度: #中等
题目:给定两个整数数组 inorder
和 postorder
,其中 inorder
是二叉树的中序遍历,postorder
是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
思路:
一共分几步:
第一步:如果数组大小为零的话,说明是空节点了。
第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。
第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点
第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)
第五步:切割后序数组,切成后序左数组和后序右数组
第六步:递归处理左区间和右区间
数组的切割要注意边界值,以左闭右开为例:
中序数组相对比较好切,找到切割点(后序数组的最后一个元素)在中序数组的位置,然后切割
后续数组最后一个节点是根节点,所以得去掉,切割点不好找,只能按照左中序数组的大小来切割,切成左后序数组和右后序数组。
实现:
cpp:
/**
* 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 {
private:
TreeNode* traversal(vector<int>& inorder, int inBegin, int inEnd, vector<int>& postorder, int poBegin, int poEnd){
if (poBegin == poEnd) return NULL;
int rootValue = postorder[poEnd - 1];
TreeNode* root = new TreeNode(rootValue);
if (postorder.size() == 1) return root;
int deIndex;
for (deIndex = inBegin; deIndex < inEnd; deIndex++){
if(inorder[deIndex] == rootValue) break;
}
int LInBegin = inBegin;
int LInEnd = deIndex;
int RInBegin = deIndex + 1;
int RInEnd = inEnd;
int LPoBegin = poBegin;
int LPoEnd = poBegin + deIndex - inBegin;
int RPoBegin = poBegin + deIndex - inBegin;
int RPoEnd = poEnd - 1;
root->left = traversal(inorder, LInBegin, LInEnd, postorder, LPoBegin, LPoEnd);
root->right = traversal(inorder, RInBegin, RInEnd, postorder, RPoBegin, RPoEnd);
return root;
}
public:
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.size() == 0 || postorder.size()==0 )return NULL;
return traversal(inorder, 0, inorder.size(), postorder, 0, postorder.size());
}
};
go:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
var (
hash map[int]int
)
func buildTree(inorder []int, postorder []int) *TreeNode {
hash = make(map[int]int)
for i, v := range inorder { // 用map保存中序序列的数值对应位置
hash[v] = i
}
// 以左闭右闭的原则进行切分
root := rebuild(inorder, postorder, len(postorder)-1, 0, len(inorder)-1)
return root
}
// rootIdx表示根节点在后序数组中的索引,l, r 表示在中序数组中的前后切分点
func rebuild(inorder []int, postorder []int, rootIdx int, l, r int) *TreeNode {
if l > r { // 说明没有元素,返回空树
return nil
}
if l == r { // 只剩唯一一个元素,直接返回
return &TreeNode{Val : inorder[l]}
}
rootV := postorder[rootIdx] // 根据后序数组找到根节点的值
rootIn := hash[rootV] // 找到根节点在对应的中序数组中的位置
root := &TreeNode{Val : rootV} // 构造根节点
// 重建左节点和右节点
root.Left = rebuild(inorder, postorder, rootIdx-(r-rootIn)-1, l, rootIn-1)
root.Right = rebuild(inorder, postorder, rootIdx-1, rootIn+1, r)
return root
}