给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:中序遍历递归实现很简单,下面题解代码主要是非递归的方式。
题解代码(C++):
/**
* 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<int> inorderTraversal(TreeNode* root) {
vector<int> res;
if(root==NULL) return res;
stack<TreeNode*> s;
TreeNode* cur = root;
while(cur!=NULL||!s.empty()){
while(cur!=NULL){
s.push(cur);
cur = cur->left;
}
if(!s.empty()){
cur = s.top();s.pop();
res.push_back(cur->val);
cur = cur->right;
}
}
return res;
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if(root==null) return res;
Stack<TreeNode> s = new Stack<TreeNode>();
TreeNode cur = root;
while(cur!=null || !s.isEmpty()){
while(cur!=null){
s.push(cur);
cur =cur.left;
}
if(!s.isEmpty()){
cur = s.pop();
res.add(cur.val);
cur = cur.right;
}
}
return res;
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]:
res = []
if root is None:
return res
s = []
cur = root
while cur is not None or len(s)>0:
while cur is not None:
s.append(cur)
cur = cur.left
if len(s)>0:
cur = s.pop()
res.append(cur.val)
cur = cur.right
return res
给出一个满足下述规则的二叉树:
root.val == 0
如果 treeNode.val == x 且 treeNode.left != null,那么treeNode.left.val == 2 * x + 1
如果 treeNode.val == x 且 treeNode.right != null,那么 treeNode.right.val == 2 * x + 2 现在这个二叉树受到「污染」,所有的treeNode.val 都变成了 -1。请你先还原二叉树,然后实现 FindElements 类:
FindElements(TreeNode* root) 用受污染的二叉树初始化对象,你需要先把它还原。 bool find(int
target) 判断目标值 target 是否存在于还原后的二叉树中并返回结果。输入: [“FindElements”,“find”,“find”]
[[[-1,null,-1]],[1],[2]]
输出:[null,false,true]
解释: FindElements findElements = newFindElements([-1,null,-1]);
findElements.find(1); // return False
findElements.find(2); // return True
示例 2:
输入: [“FindElements”,“find”,“find”,“find”]
[[[-1,-1,-1,-1,-1]],[1],[3],[5]]
输出: [null,true,true,false]
解释:
FindElements findElements = new FindElements([-1,-1,-1,-1,-1]);
findElements.find(1); // return True
findElements.find(3); // return
True findElements.find(5); // return False
示例 3:输入: [“FindElements”,“find”,“find”,“find”,“find”]
[[[-1,null,-1,-1,null,-1]],[2],[3],[4],[5]]
输出:
[null,true,false,false,true]
解释: FindElements findElements = new FindElements([-1,null,-1,-1,null,-1]); findElements.find(2); // returnTrue
findElements.find(3); // return False
findElements.find(4); //return False
findElements.find(5); // return True提示:
TreeNode.val == -1 二叉树的高度不超过 20 节点的总数在 [1, 104] 之间 调用 find() 的总次数在 [1, 104] 之间 0 <= target <= 106
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-elements-in-a-contaminated-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:首先是要修复受污染的树,本质上修改结点的值,首先是把根节点值置为0,然后递归修复左右子树,如果左右孩子存在,则根据传入的参数修改值,如果左右孩子不存在,则返回。
修复完树之后是查找,在修复的时候就把新值加入到set集合中,调用find()函数时可以使用set集合查找的方法即可。
题解代码(C++):
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class FindElements {
public:
set<int> myset;
void dfs(TreeNode* root,int val){
if(root==NULL) return;
root->val=val;
myset.insert(root->val);
dfs(root->left,2*root->val+1);
dfs(root->right,2*root->val+2);
}
FindElements(TreeNode* root) {
root->val = 0;
dfs(root->left,2*root->val+1);
dfs(root->right,2*root->val+2);
}
bool find(int target) {
return myset.find(target)!=myset.end();
}
};
/**
* Your FindElements object will be instantiated and called as such:
* FindElements* obj = new FindElements(root);
* bool param_1 = obj->find(target);
*/
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class FindElements {
Set<Integer> myset;
public void dfs(TreeNode root,int val){
if(root==null) return;
root.val = val;
myset.add(val);
dfs(root.left,2*val+1);
dfs(root.right,2*val+2);
}
public FindElements(TreeNode root) {
this.myset = new HashSet<>();
root.val = 0;
dfs(root.left,1);
dfs(root.right,2);
}
public boolean find(int target) {
return this.myset.contains(target);
}
}
/**
* Your FindElements object will be instantiated and called as such:
* FindElements obj = new FindElements(root);
* boolean param_1 = obj.find(target);
*/
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class FindElements:
def __init__(self, root: TreeNode):
self.myset = set()
root.val=0
self.dfs(root.left,1)
self.dfs(root.right,2)
def dfs(self,root:TreeNode,val:int):
if root is None:
return None
root.val=val
self.myset.add(val)
self.dfs(root.left,2*val+1)
self.dfs(root.right,2*val+2)
def find(self, target: int) -> bool:
return target in self.myset
# Your FindElements object will be instantiated and called as such:
# obj = FindElements(root)
# param_1 = obj.find(target)
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
说明: 你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
示例 1:
输入: root = [3,1,4,null,2], k = 13 / \ 1 4 \ 2
输出: 1
示例2:
输入: root = [5,3,6,2,4,null,null,1], k = 35 / \ 3 6 / \ 2 4 / 1
输出: 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:二叉搜索树的中序遍历是升序的结果,找到第k个访问的结点值即可,可以递归遍历,也可以非递归遍历。
题解代码(C++):
/**
* 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 count,res;
void dfs(TreeNode* root,int &k){
if(root==NULL||this->count==k) return;
dfs(root->left,k);
this->count++;
if(this->count==k) {this->res = root->val;k--;return;}
dfs(root->right,k);
}
int kthSmallest(TreeNode* root, int k) {
this->count=0;
dfs(root,k);
return this->res;
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int count =0;
int res;
public void dfs(TreeNode root,int k){
if(root==null || this.count==k) return;
dfs(root.left,k);
this.count++;
if(this.count==k) {this.res = root.val;return;}
dfs(root.right,k);
}
public int kthSmallest(TreeNode root, int k) {
this.count = 0;
dfs(root,k);
return this.res;
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
res,count = 0,0
s = []
cur = root
while cur is not None or len(s)>0:
while cur is not None:
s.append(cur)
cur = cur.left
if len(s)>0:
cur = s.pop()
count+=1
if count ==k:
res = cur.val
cur = cur.right
return res
给你一棵以 root 为根的二叉树和一个整数 target ,请你删除所有值为 target 的 叶子节点 。
注意,一旦删除值为 target 的叶子节点,它的父节点就可能变成叶子节点;如果新叶子节点的值恰好也是 target,那么这个节点也应该被删除。也就是说,你需要重复此过程直到不能继续删除。
示例 1:
输入:root = [1,2,3,2,null,2,4], target = 2
输出:[1,null,3,null,4]
解释:
上面左边的图中,绿色节点为叶子节点,且它们的值与 target 相同(同为 2 ),它们会被删除,得到中间的图。
有一个新的节点变成了叶子节点且它的值与 target 相同,所以将再次进行删除,从而得到最右边的图。
示例 2:
输入:root = [1,3,3,3,2], target = 3
输出:[1,3,null,null,2]
示例 3:
输入:root = [1,2,null,2,null,2], target = 2
输出:[1]
解释:每一步都删除一个绿色的叶子节点(值为
2)。 示例 4:输入:root = [1,1,1], target = 1 输出:[] 示例 5:
输入:root = [1,2,3], target = 1 输出:[1,2,3]
提示:
1 <= target <= 1000 每一棵树最多有 3000 个节点。 每一个节点值的范围是 [1, 1000] 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/delete-leaves-with-a-given-value
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:本题关键在于一旦删除值为 target 的叶子节点,它的父节点就可能变成叶子节点,所以大致思路是:
1、先把左子树当成一棵树,进行删除叶子结点的操作,最后返回删除后的树,有可能左子树都删完了,返回空;右子树同理。
2、经过步骤1,也更新了左右孩子,这时候再判断是否为空和根节点的值是否为target,如果是就删除,返回NULL,如果不是就返回根节点。
3、左子树和右子树的操作都是递归进行。
题解代码(C++):
/**
* 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:
TreeNode* removeLeafNodes(TreeNode* root, int target) {
if(root==NULL) return NULL;
root->left = removeLeafNodes(root->left,target);
root->right = removeLeafNodes(root->right,target);
if(root->left==NULL && root->right==NULL && root->val==target)
return NULL;
else
return root;
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode removeLeafNodes(TreeNode root, int target) {
if(root==null) return null;
root.left = removeLeafNodes(root.left,target);
root.right= removeLeafNodes(root.right,target);
if(root.left==null && root.right==null && root.val ==target)
return null;
else
return root;
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def removeLeafNodes(self, root: TreeNode, target: int) -> TreeNode:
if root is None:
return None
root.left=self.removeLeafNodes(root.left,target)
root.right=self.removeLeafNodes(root.right,target)
if root.left is None and root.right is None and root.val == target:
return None
else:
return root
给定一个二叉树,在树的最后一行找到最左边的值。
示例 1:
输入:
2 / \ 1 3
输出: 1
示例 2:
输入:
1 / \ 2 3 / / \ 4 5 6 / 7
输出: 7
注意: 您可以假设树(即给定的根节点)不为 NULL。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-bottom-left-tree-value
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:层次遍历,每层输出到一个vector,取最后一个vector的第一个元素即可。
题解代码(C++):
/**
* 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 findBottomLeftValue(TreeNode* root) {
vector<vector<int>> res;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int count = q.size();
vector<int> v;
while(count>0){
TreeNode* cur = q.front();q.pop();
v.push_back(cur->val);
if(cur->left!=NULL) q.push(cur->left);
if(cur->right!=NULL) q.push(cur->right);
count--;
}
res.push_back(v);
}
return res[res.size()-1][0];
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int findBottomLeftValue(TreeNode root) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Queue<TreeNode> q = new LinkedList<TreeNode>();
q.offer(root);
while(!q.isEmpty()){
int count = q.size();
List<Integer> v = new ArrayList<>();
while(count>0){
TreeNode cur = q.poll();
v.add(cur.val);
if(cur.left!=null) q.offer(cur.left);
if(cur.right!=null) q.offer(cur.right);
count--;
}
res.add(v);
}
return res.get(res.size()-1).get(0);
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
res = []
q = []
q.append(root)
while len(q)>0:
count = len(q)
v = []
while count>0:
cur = q.pop(0)
v.append(cur.val)
if cur.left is not None:
q.append(cur.left)
if cur.right is not None:
q.append(cur.right)
count-=1
res.append(v)
return res[-1][0]
给定一个二叉树,原地将它展开为链表。
例如,给定二叉树
1 / \ 2 5 / \ \ 3 4 6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:很简单的思路,先把左子树展平,然后把右子树展平,最后连接起来即可。
主要分为两种情况:如果没有左子树,直接展平右子树即可
如果有左子树,先展平左子树,然后左子树最后一个结点连接到展平后的右子树,然后修改根节点的连接。
题解代码(C++):
/**
* 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:
TreeNode* flattenHelper(TreeNode* root){
if(root==NULL) return NULL;
if(root->left!=NULL){
flattenHelper(root->left);
TreeNode* join = root->left;
while(join->right!=NULL) join = join->right;
join->right = flattenHelper(root->right);
root->right = root->left;
root->left=NULL;
}else{
root->right=flattenHelper(root->right);
}
return root;
}
void flatten(TreeNode* root) {
if(root==NULL) return;
flattenHelper(root);
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode flattenHelper(TreeNode root){
if(root==null) return null;
if(root.left==null){
root.right = flattenHelper(root.right);
}else{
flattenHelper(root.left);
TreeNode join = root.left;
while(join.right!=null) join = join.right;
join.right = flattenHelper(root.right);
root.right = root.left;
root.left = null;
}
return root;
}
public void flatten(TreeNode root) {
if(root==null) return;
flattenHelper(root);
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
self.flattenHelper(root)
def flattenHelper(self,root:TreeNode)->TreeNode:
if root is None:
return None
if root.left is None:
root.right = self.flattenHelper(root.right)
else:
self.flattenHelper(root.left)
join = root.left
while join.right is not None:
join = join.right
join.right = self.flattenHelper(root.right)
root.right = root.left
root.left = None
return root
给出一个完全二叉树,求出该树的节点个数。
说明:
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例:
输入:
1 / \ 2 3 / \ / 4 5 6
输出: 6
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-complete-tree-nodes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:最简单的思路就是利用遍历,为线性时间。
但是最佳的是利用完全二叉树的特性,效率较高。
假设完全二叉树的深度为d,那么除去最底层的结点,就有2d-1-1个结点,然后统计一下最底层的节点数即可。
现在问题是如何统计最底层的节点数?
可以使用二分查找!!!
把最底层的结点看成是一个数组:
虚线代表的是不存在的结点,首先第一轮是检查middle的结点存在不存在;
然后第二轮再检查middle位置的结点是否存在,最终定位到letf==right的结点
由此就能统计到最底层结点的数量了。
题解代码(C++):
/**
* 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 res = 0;
void dfs(TreeNode* root){
if(root==NULL) return;
this->res++;
dfs(root->left);
dfs(root->right);
}
int countNodes(TreeNode* root) {
this->res = 0;
dfs(root);
return this->res;
}
};
/**
* 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:
bool exists(TreeNode* root,int index,int depth){
int left = 0,right=(1<<depth)-1;
int mid = 0;
TreeNode* cur = root;
while(depth>0){
mid = (left+right)/2;
if(index<=mid) {cur = cur->left;right=mid;}
else {cur = cur->right;left=mid+1;}
depth--;
}
return cur!=NULL;
}
int countNodes(TreeNode* root) {
if(root==NULL) return 0;
int depth = 0;
TreeNode* cur=root;
while(cur!=NULL){
depth++;
cur = cur->right;
}
int top = (1<<depth)-1;//最底层以上的结点数量
//下面计算最底层的结点数量
int left=0,right=(1<<depth)-1,mid=0;
while(left<right){
mid = (left+right)/2;
if(exists(root,mid,depth)) left=mid+1;
else right = mid-1;
}
if(exists(root,left,depth)) return top+left+1;
else return top+left;
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
boolean exists(TreeNode root,int index,int depth){
int left = 0,right=(1<<depth)-1;
int mid =0;
TreeNode cur = root;
while(depth>0){
mid = (left+right)/2;
if(index<=mid) {cur = cur.left;right=mid;}
else{cur = cur.right;left=mid+1;}
depth--;
}
return cur!=null;
}
public int countNodes(TreeNode root) {
if(root==null) return 0;
int depth = 0;
TreeNode cur =root;
while(cur!=null){
depth++;
cur=cur.right;
}
int top = (1<<depth)-1;
int left=0,right=(1<<depth)-1,mid=0;
while(left<right){
mid = (left+right)/2;
if(exists(root,mid,depth)) left=mid+1;
else right = mid-1;
}
if(exists(root,left,depth)) return top+left+1;
else return top+left;
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def exists(self,root:TreeNode,index:int,depth:int)->bool:
left,right=0,2**depth-1
cur = root
while depth>0:
mid = (left+right)//2
if index<= mid:
cur = cur.left
right = mid
else:
cur = cur.right
left = mid+1
depth-=1
return cur is not None
def countNodes(self, root: TreeNode) -> int:
if root is None:
return 0
depth = 0
cur = root
while cur is not None:
depth+=1
cur = cur.right
top = 2**depth-1
left,right = 0,2**depth-1
while left<right:
mid = (left+right)//2
if self.exists(root,mid,depth):
left = mid+1
else:
right = mid-1
if self.exists(root,left,depth):
return top+left+1
else:
return top+left
根据一棵树的中序遍历与后序遍历构造二叉树。
注意: 你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树:
3 / \ 9 20 / \ 15 7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:可以由中序遍历和后序遍历唯一确定一棵二叉树,根据后序遍历可以确定根节点,而中序遍历可以确定分组。
题解代码(C++):
/**
* 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<int> postorder;
int index;
map<int,int> mymap;
TreeNode* buildTreeHelper(int left,int right){
if(left>right) return NULL;
int val = this->postorder[this->index--];
TreeNode* root = new TreeNode(val);
root->right = buildTreeHelper(this->mymap[val]+1,right);
root->left = buildTreeHelper(left,this->mymap[val]-1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
this->mymap.clear();
for(int i=0;i<inorder.size();i++){
this->mymap[inorder[i]] = i;
}
this->index = inorder.size()-1;
this->postorder = postorder;
return buildTreeHelper(0,inorder.size()-1);
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int index;
int[] postorder;
Map<Integer,Integer> mymap = new HashMap<>();
public TreeNode buildTreeHelper(int left,int right){
if(left>right) return null;
int val = this.postorder[this.index--];
TreeNode root = new TreeNode(val);
root.right = buildTreeHelper(this.mymap.get(val)+1,right);
root.left = buildTreeHelper(left,this.mymap.get(val)-1);
return root;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.index = postorder.length-1;
this.postorder = postorder;
for(int i=0;i<inorder.length;i++){
this.mymap.put(inorder[i],i);
}
return buildTreeHelper(0,inorder.length-1);
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
def helper(left:int,right:int)->TreeNode:
if left>right:
return None
val = postorder.pop()
root = TreeNode(val)
root.right = helper(mymap[val]+1,right)
root.left = helper(left,mymap[val]-1)
return root
mymap = {val:idx for idx,val in enumerate(inorder)}
return helper(0,len(inorder)-1)
在一棵无限的二叉树上,每个节点都有两个子节点,树中的节点 逐行 依次按 “之” 字形进行标记。
如下图所示,在奇数行(即,第一行、第三行、第五行……)中,按从左到右的顺序进行标记;
而偶数行(即,第二行、第四行、第六行……)中,按从右到左的顺序进行标记。
给你树上某一个节点的标号 label,请你返回从根节点到该标号为 label 节点的路径,该路径是由途经的节点标号所组成的。
示例 1:
输入:label = 14 输出:[1,3,4,14]
示例 2:
输入:label = 26 输出:[1,2,6,10,26]
提示:1 <= label <= 106
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-in-zigzag-labelled-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:找规律的题目。
假如结点的值都转化为二进制,就得到上图的树,怎么找规律呢?
例如label=14,输出结果为[1,3,4,14]
那么14=1110b 如何转为4=0100b呢?
首先右移一位得到0111b=7,然后最后两位取反得到0100b=4
0100b=4右移一位得到0010b,然后最后一位取反得到0011b=3
0011b=3右移一位得到0001b,然后最后0位取反得到0001b=1
就是这么一个规律。
怎么知道是按最后多少位取反呢?首先是确定label所在层数d,d=上取整log2(label),例如label=14,d=4,2=d-2;
如何按最后两位取反?使用异或运算,0异或a = a,1异或a = a的取反。
题解代码(C++):
class Solution {
public:
vector<int> pathInZigZagTree(int label) {
vector<int> res;
int d = log(label)/log(2);
if(d==0) {res.push_back(1);return res;}
int mask = (1<<(d-1))-1;
while(label>1){
res.push_back(label);
label = label>>1;
label = label ^ mask;
mask = mask>>1;
}
res.push_back(1);
reverse(res.begin(),res.end());
return res;
}
};
题解代码(Java):
class Solution {
public List<Integer> pathInZigZagTree(int label) {
List<Integer> res = new LinkedList<Integer>();
int d = (int)(Math.log(label)/Math.log(2));
if(d==0){res.add(1);return res;}
int mask = (1<<(d-1))-1;
while(label>1){
res.add(label);
label = label>>1;
label = label^mask;
mask = mask>>1;
}
res.add(1);
Collections.reverse(res);
return res;
}
}
题解代码(Python):
class Solution:
def pathInZigZagTree(self, label: int) -> List[int]:
res = []
d = int(log(label)/log(2))
if d ==0:
res.append(1)
return res
mask = (1<<(d-1))-1
while label>1:
res.append(label)
label = label>>1
label = label ^ mask
mask = mask >>1
res.append(1)
res.reverse()
return res
给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币。
在一次移动中,我们可以选择两个相邻的结点,然后将一枚硬币从其中一个结点移动到另一个结点。(移动可以是从父结点到子结点,或者从子结点移动到父结点。)。
返回使每个结点上只有一枚硬币所需的移动次数。
示例 1:
输入:[3,0,0] 输出:2
解释:从树的根结点开始,我们将一枚硬币移到它的左子结点上,一枚硬币移到它的右子结点上。
示例 2:
输入:[0,3,0] 输出:3 解释:从根结点的左子结点开始,我们将两枚硬币移到根结点上
[移动两次]。然后,我们把一枚硬币从根结点移到右子结点上。 示例 3:
输入:[1,0,2] 输出:2
示例 4:
输入:[1,0,0,null,3] 输出:4
提示:
1<= N <= 100
0 <= node.val <= N
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/distribute-coins-in-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:
这个问题是移动金币的问题,首先有左右孩子的结点有两个移动方向,若其还有父节点,那么就有三个移动方向,这是很不便于分析的。
如果是只有一个孩子的结点就有一个移动方向,若其还有父节点,那么也有两个移动方向,也是不便于分析。
没有孩子的结点,也就是叶子节点,移动方向就只有一个了,看叶子结点的值就能知道移进或移出金币的步数:abs(val-1)
总绝对值为4,表示需要4步才能完成对叶子结点的金币移动。
此时,叶子结点就不再考虑了,而是要考虑倒数第二层的结点。
为什么第二层的左边的0结点变成1了呢?可以理解成它从左右孩子结点分别是移入2个,移出1个,剩下1个。
就是上图这种样子,而且步数也计算了abs(2)+abs(-1) =3,需要3步能完成。
类似这样,从叶子结点一层层解决,使用后序遍历的方式就可以完成。
题解代码(C++):
/**
* 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 dfs(TreeNode* root,int &res){
if(root==NULL) return 0;
int left = dfs(root->left,res);//计算左子树完成多余(所需)的金币数
int right = dfs(root->right,res);//计算右子树完成多余(所需)的金币数
res= res + abs(left) + abs(right);//移动步数累加
return root->val+left+right-1;//当前结点多余(所需)的金币数
}
int distributeCoins(TreeNode* root) {
int res =0;
dfs(root,res);
return res;
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int res =0;
public int dfs(TreeNode root){
if(root==null) return 0;
int left = dfs(root.left);
int right = dfs(root.right);
this.res = this.res + Math.abs(left) + Math.abs(right);
return root.val+left+right-1;
}
public int distributeCoins(TreeNode root) {
this.res = 0;
dfs(root);
return this.res;
}
}
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def __init__(self):
self.res = 0
def dfs(self,root:TreeNode)->int:
if root is None:
return 0
left = self.dfs(root.left)
right = self.dfs(root.right)
self.res = self.res + abs(left)+abs(right)
return root.val+left+right-1
def distributeCoins(self, root: TreeNode) -> int:
self.res = 0
self.dfs(root)
return self.res