给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target。
其中,克隆树 cloned 是原始树 original 的一个 副本 。 请找出在树 cloned 中,与 target 相同的节点,并返回对该节点的引用(在 C/C++ 等有指针的语言中返回 节点指针,其他语言返回节点本身)。 注意: 你不能对两棵二叉树,以及target 节点进行更改。 只能 返回对克隆树 cloned 中已有的节点的引用。输入: tree = [7,4,3,null,null,6,19], target = 3
输出: 3
解释: 上图画出了树original 和 cloned。target 节点在树 original 中,用绿色标记。
答案是树 cloned中的黄颜色的节点(其他示例类似)。
示例 2:
输入: tree = [7], target = 7
输出: 7
示例 3:
输入: tree = [8,null,6,null,5,null,4,null,3,null,2,null,1], target = 4
输出: 4
示例 4:
输入: tree = [1,2,3,4,5,6,7,8,9,10], target = 5
输出: 5
示例 5:
输入: tree = [1,2,null,3], target = 2
输出: 2提示: 树中节点的数量范围为 [1, 10^4] 。 同一棵树中,没有值相同的节点。 target 节点是树 original
中的一个节点,并且不会是 null 。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:本质还是递归遍历,既然cloned 树是original树的克隆,那就需要同步遍历,只要找到(original遍历的当前结点=target结点)就返回cloned树对应的结点。
题解代码(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* getTargetCopy(TreeNode* original, TreeNode* cloned, TreeNode* target) {
if(original==NULL || cloned==NULL || target==NULL) return NULL;
if(original==target) return cloned;
TreeNode* l = getTargetCopy(original->left,cloned->left,target);
TreeNode* r = getTargetCopy(original->right,cloned->right,target);
return l !=NULL?l:r;
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public final TreeNode getTargetCopy(final TreeNode original, final TreeNode cloned, final TreeNode target) {
if(original==null || cloned==null||target==null) return null;
if(original==target) return cloned;
TreeNode l = getTargetCopy(original.left,cloned.left,target);
TreeNode r = getTargetCopy(original.right,cloned.right,target);
return l==null?r:l;
}
}
题解代码(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 getTargetCopy(self, original: TreeNode, cloned: TreeNode, target: TreeNode) -> TreeNode:
if original is None or cloned is None or target is None:
return None
if original is target:
return cloned
l = self.getTargetCopy(original.left,cloned.left,target)
r = self.getTargetCopy(original.right,cloned.right,target)
return l if l is not None else r
给你一棵二叉树,请你返回层数最深的叶子节点的和。
输入:root = [1,2,3,4,5,null,6,7,null,null,null,null,8] 输出:15
提示:
树中节点数目在 1 到 10^4 之间。 每个节点的值在 1 到 100 之间。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/deepest-leaves-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:记得以前层次遍历【2.3、102. 二叉树的层序遍历】中,得到输出的遍历结果 [ [3], [9,20], [15,7] ] 吗?
就把输出结果最后的一个数组累加和输出即可。(本题属于回顾复习题)
也可以先求树的高度,然后再递归,深度满足的叶子结点值就可以加到累加和中。
题解代码(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 deepestLeavesSum(TreeNode* root) {
int res = 0;
if(root!=NULL){
queue<TreeNode*> q;
q.push(root);
vector<vector<int>> temp;
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--;
}
temp.push_back(v);
}
for(int i=0;i<temp[temp.size()-1].size();i++){
res+=temp[temp.size()-1][i];
}
}
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 int deepestLeavesSum(TreeNode root) {
if(root==null) return 0;
int res = 0;
List<List<Integer>> temp = new ArrayList<List<Integer>>();
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
int count = q.size();
List<Integer> v = new ArrayList<>();
while(count>0){
TreeNode t = q.poll();
v.add(t.val);
if(t.left!=null) q.offer(t.left);
if(t.right!=null) q.offer(t.right);
count--;
}
temp.add(v);
}
int last = temp.size()-1;
for(int a :temp.get(last))
res+=a;
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 deepestLeavesSum(self, root: TreeNode) -> int:
if root is None:
return 0
q = []
temp = []
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
temp.append(v)
return sum(temp[-1])
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
二叉树的根是数组中的最大元素。
左子树是通过数组中最大值左边部分构造出的最大二叉树。
右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
示例 :
输入:[3,2,1,6,0,5] 输出:返回下面这棵树的根节点:6 / \ 3 5 \ / 2 0 \ 1
提示:
给定的数组的大小在 [1, 1000] 之间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:可以递归构造树,首先要找到数组中最大值,然后记录索引mid,根据最大值创建结点,结点左右子树根据索引切片得到的数组来构造。
题解代码(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* constructMaximumBinaryTreeHelper(vector<int>& nums,int l,int r){
if(l>r) return NULL;
int max = INT_MIN;
int mid = 0;
for(int i=l;i<=r;i++){
if(nums[i]>max) {
max = nums[i];
mid = i;
}
}
TreeNode* root = new TreeNode(nums[mid]);
root->left = constructMaximumBinaryTreeHelper(nums,l,mid-1);
root->right = constructMaximumBinaryTreeHelper(nums,mid+1,r);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size()!=0){
TreeNode* res = constructMaximumBinaryTreeHelper(nums,0,nums.size()-1);
return res;
}else{
return NULL;
}
}
};
题解代码(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 constructMaximumBinaryTreeHelper(int[] nums,int l,int r){
if(l>r) return null;
int max = Integer.MIN_VALUE;
int mid = 0;
for(int i=l;i<=r;i++){
if(max<nums[i]) {
max = nums[i];
mid = i;
}
}
TreeNode root = new TreeNode(nums[mid]);
root.left = constructMaximumBinaryTreeHelper(nums,l,mid-1);
root.right = constructMaximumBinaryTreeHelper(nums,mid+1,r);
return root;
}
public TreeNode constructMaximumBinaryTree(int[] nums) {
if(nums.length==0) return null;
else return constructMaximumBinaryTreeHelper(nums,0,nums.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 constructMaximumBinaryTreeHelper(self,nums:List[int],l:int,r:int) ->TreeNode:
if l>r:
return None
MaxNum = -pow(2,32)
mid = 0
for i in range(l,r+1):
if MaxNum<nums[i]:
MaxNum = nums[i]
mid = i
root = TreeNode(nums[mid])
root.left = self.constructMaximumBinaryTreeHelper(nums,l,mid-1)
root.right = self.constructMaximumBinaryTreeHelper(nums,mid+1,r)
return root
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
if len(nums)==0:
return None
else:
return self.constructMaximumBinaryTreeHelper(nums,0,len(nums)-1)
给你一棵二叉树,请你返回满足以下条件的所有节点的值之和:该节点的祖父节点的值为偶数。
(一个节点的祖父节点是指该节点的父节点的父节点。) 如果不存在祖父节点值为偶数的节点,那么返回 0 。
示例:输入:root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5]
输出:18
解释:图中红色节点的祖父节点的值为偶数,蓝色节点为这些红色节点的祖父节点。提示:
树中节点的数目在 1 到 10^4 之间。
每个节点的值在 1 到 100 之间。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sum-of-nodes-with-even-valued-grandparent
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:遍历一遍所有的结点,如果当前结点的值是偶数,就看有没有孙子结点,如果有就加入到累加和,最后返回即可。
题解代码(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;
if(root->val%2==0){
if(root->left!=NULL){
if(root->left->left!=NULL) this->res+=root->left->left->val;
if(root->left->right!=NULL) this->res+=root->left->right->val;
}
if(root->right!=NULL){
if(root->right->left!=NULL) this->res+=root->right->left->val;
if(root->right->right!=NULL) this->res+=root->right->right->val;
}
}
dfs(root->left);
dfs(root->right);
}
int sumEvenGrandparent(TreeNode* root) {
if(root==NULL) return 0;
this->res = 0;
dfs(root);
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 res;
public void dfs(TreeNode root){
if(root==null) return;
if(root.val%2==0){
if(root.left!=null){
if(root.left.left!=null) this.res+=root.left.left.val;
if(root.left.right!=null) this.res+=root.left.right.val;
}
if(root.right!=null){
if(root.right.left!=null) this.res+=root.right.left.val;
if(root.right.right!=null) this.res+=root.right.right.val;
}
}
dfs(root.left);
dfs(root.right);
}
public int sumEvenGrandparent(TreeNode root) {
if(root==null) return 0;
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):
if root is None:
return None
if root.val % 2 == 0:
if root.left is not None:
if root.left.left is not None:
self.res +=root.left.left.val
if root.left.right is not None:
self.res+= root.left.right.val
if root.right is not None:
if root.right.left is not None:
self.res +=root.right.left.val
if root.right.right is not None:
self.res+= root.right.right.val
self.dfs(root.left)
self.dfs(root.right)
def sumEvenGrandparent(self, root: TreeNode) -> int:
if root is None:
return 0
self.res = 0
self.dfs(root)
return self.res
给定二叉搜索树(BST)的根节点和要插入树中的值,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 保证原始二叉搜索树中不存在新值。
注意,可能存在多种有效的插入方式,只要树在插入后仍保持为二叉搜索树即可。 你可以返回任意有效的结果。
例如,
给定二叉搜索树:
4 / \ 2 7 / \ 1 3
和 插入的值: 5 你可以返回这个二叉搜索树:
4 / \ 2 7 / \ / 1 3 5 或者这个树也是有效的: 5 / \ 2 7 / \ 1 3 \ 4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/insert-into-a-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:根据二叉搜索树的特性,查找到要插入的位置,顺势插入即可。
题解代码(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:
void searchBST(TreeNode* root,int &val){
if(root==NULL) return;
if(root->val>val){
if(root->left==NULL) {root->left = new TreeNode(val);return;}
else searchBST(root->left,val);
}else{
if(root->right==NULL) {root->right = new TreeNode(val);return;}
else searchBST(root->right,val);
}
}
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==NULL) return NULL;
searchBST(root,val);
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 void searchBST(TreeNode root,int val){
if(root==null) return;
if(root.val>val){
if(root.left==null){root.left=new TreeNode(val); return;}
else searchBST(root.left,val);
}else{
if(root.right==null){root.right=new TreeNode(val); return;}
else searchBST(root.right,val);
}
}
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root==null) return null;
searchBST(root,val);
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 search(self,root:TreeNode,val:int):
if root is None:
return None
if root.val>val:
if root.left is None:
root.left = TreeNode(val)
else:
self.search(root.left,val)
else:
if root.right is None:
root.right = TreeNode(val)
else:
self.search(root.right,val)
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
if root is None:
return None
self.search(root,val)
return root
满二叉树是一类二叉树,其中每个结点恰好有 0 或 2 个子结点。
返回包含 N 个结点的所有可能满二叉树的列表。 答案的每个元素都是一个可能树的根结点。
答案中每个树的每个结点都必须有 node.val=0。
你可以按任何顺序返回树的最终列表。
示例:输入:7
输出:[[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,null,null,null,null,0,0],[0,0,0,0,0,null,null,0,0]]
解释:
提示:
1 <= N <= 20
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-possible-full-binary-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:有点难度,有点挑战。首先要确定一下N的取值范围,如果N<1,则构不成树,如果N是偶数,就不满足 每个结点恰好有 0 或 2 个子结点这个条件。因为每个结点0或2个子结点,那么这种树的分支树一定为偶数,而N为偶数的时候,构成的树分支树却是奇数,所以N不能为偶数。
接下来还需要分析给出N(奇数),可以构建多少棵满足条件的树?
例如:N=7,先构建一个根节点,则剩下6个结点,可以分配给左右孩子结点数的方案有:(1,5)、(3,3)、(5,1),那么就是至少可以构建3棵,如果N=5,分配方案有:(1,3),(3,1),至少可以构建2棵,如果N=3,分配方案只有(1,1),只能构建一棵树,如果N=1,只有一个结点的树。
根据上面分析,N=7应该是可以构建5棵树,N=5是可以构建2棵树,N=1或N=3都只能构建一棵树。
总结:
假设:vector
1、根据分配的方案不同,需要一个遍历:
for(int i=1;i<=N-2;i+=2) (i、N-1-i)表示一种分配方案
2、左边可选的子树:allPossibleFBT(i) 返回的树的vector
右边可选的子树:allPossibleFBT(N-1-i) 返回的树的vector
3、取2中的两个vector的组合作为新创结点的左右孩子,最后把新创的结点加入到res结果中去,最后循环完毕返回即可。
题解代码(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<TreeNode*> allPossibleFBT(int N) {
vector<TreeNode*> res;
if(N % 2 == 0) return res;
if(N == 1) {res.push_back(new TreeNode(0));return res;}
for(int i=1;i<=N-2;i+=2){
vector<TreeNode*> left = allPossibleFBT(i);
vector<TreeNode*> right = allPossibleFBT(N-1-i);
for(int j=0;j<left.size();++j){
for(int k=0;k<right.size();++k){
TreeNode *root = new TreeNode(0);
root->left = left[j];
root->right = right[k];
res.push_back(root);
}
}
}
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<TreeNode> allPossibleFBT(int N) {
List<TreeNode> res = new ArrayList<TreeNode>();
if(N%2==0) return res;
if(N==1){
res.add(new TreeNode(0));
return res;
}
for(int i=1;i<=N-2;i+=2){
List<TreeNode> left = allPossibleFBT(i);
List<TreeNode> right = allPossibleFBT(N-i-1);
for(TreeNode l:left){
for(TreeNode r:right){
TreeNode root = new TreeNode(0);
root.left = l;
root.right = r;
res.add(root);
}
}
}
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 allPossibleFBT(self, N: int) -> List[TreeNode]:
res = []
if N%2 ==0:
return res
if N==1:
res.append(TreeNode(0))
return res
for i in range(1,N,2):
lefts = self.allPossibleFBT(i)
rights = self.allPossibleFBT(N-i-1)
for l in lefts:
for r in rights:
root = TreeNode(0)
root.left = l
root.right = r
res.append(root)
return res
给你 root1 和 root2 这两棵二叉搜索树。
请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序。.
输入:root1 = [2,1,4], root2 = [1,0,3] 输出:[0,1,1,2,3,4]
示例 2:输入:root1 = [0,-10,10], root2 = [5,1,7,0,2] 输出:[-10,0,0,1,2,5,7,10]
示例 3:输入:root1 = [], root2 = [5,1,7,0,2] 输出:[0,1,2,5,7]
示例 4:输入:root1 = [0,-10,10], root2 = [] 输出:[-10,0,10]
示例 5:
输入:root1 = [1,null,8], root2 = [8,1] 输出:[1,1,8,8]
提示:
每棵树最多有 5000 个节点。 每个节点的值在 [-10^5, 10^5] 之间。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-elements-in-two-binary-search-trees
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:两棵二叉搜索树分别中序遍历,然后得到两个升序的数组,最终合并到一个数组即可,思路清晰明了。
时间复杂度:O(M+N) 遍历一遍树和遍历一遍数组即可
空间复杂度:O(M+N) 额外的数组来存放遍历输出结果
题解代码(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:
void dfs(TreeNode* root,vector<int> &res){
if(root==NULL) return;
dfs(root->left,res);
res.push_back(root->val);
dfs(root->right,res);
}
vector<int> getAllElements(TreeNode* root1, TreeNode* root2) {
vector<int> v1;
vector<int> v2;
dfs(root1,v1);
dfs(root2,v2);
vector<int> res;
int i=0,j=0;
while(i<v1.size() || j<v2.size()){
if(i<v1.size()&&(j==v2.size()||v1[i]<v2[j])){
res.push_back(v1[i++]);
}else{
res.push_back(v2[j++]);
}
}
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 void dfs(TreeNode root,List<Integer> res){
if(root==null) return;
dfs(root.left,res);
res.add(root.val);
dfs(root.right,res);
}
public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
List<Integer> v1 = new ArrayList<Integer>();
List<Integer> v2 = new ArrayList<Integer>();
List<Integer> res = new ArrayList<Integer>();
dfs(root1,v1);
dfs(root2,v2);
int i=0,j=0;
while(i<v1.size()||j<v2.size()){
if(i<v1.size()&&(j==v2.size()||v1.get(i)<v2.get(j))){
res.add(v1.get(i));
i++;
}else{
res.add(v2.get(j));
j++;
}
}
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 dfs(self,root:TreeNode,res:List[int]):
if root is None:
return None
self.dfs(root.left,res)
res.append(root.val)
self.dfs(root.right,res)
def getAllElements(self, root1: TreeNode, root2: TreeNode) -> List[int]:
v1,v2 = [],[]
self.dfs(root1,v1)
self.dfs(root2,v2)
res = []
i,j = 0,0
while i<len(v1) or j <len(v2):
if i<len(v1) and (j==len(v2) or v1[i]<v2[j]):
res.append(v1[i])
i+=1
else:
res.append(v2[j])
j+=1
return res
给定二叉树根结点 root ,此外树的每个结点的值要么是 0,要么是 1。
返回移除了所有不包含 1 的子树的原二叉树。
( 节点 X 的子树为 X 本身,以及所有 X 的后代。)
示例1: 输入: [1,null,0,0,1] 输出: [1,null,0,null,1] 解释: 只有红色节点满足条件“所有不包含
1 的子树”。 右图为返回的答案。
示例2: 输入: [1,0,1,0,0,0,1] 输出: [1,null,1,null,1]
示例3: 输入: [1,1,0,1,1,0,1,0] 输出: [1,1,0,1,1,null,1]
说明:
给定的二叉树最多有 100 个节点。 每个节点的值只会为 0 或 1 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-pruning
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:本题使用递归来剪枝,试想一棵树,如果root为NULL,则返回false,表示所给的树没有含有1 的结点。
当root不为空的时候:
如果它的左子树没有含有1的结点,则令左孩子为NULL,同理右子树没有含有1的结点,则令右孩子为NULL。
在裁剪了左右子树之后,如果只剩下root一个根节点,即左右孩子均为NULL,表示左右子树都没有含有1的结点,那么就再判断根节点root的值,如果root->val为1,则返回true,表示root这棵树有1的结点,如果root->val为0,则返回fasle,表示root这棵树没有1的结点。
其他的情况就返回true,因为剪枝后的root树还有左右孩子的话,就表示这root树含有1 的结点。
简单框架:
bool dfs(TreeNode* root){
if(root==NULL) return false;
if(!dfs(root->left)){
root->left = NULL;
}
if(!dfs(root->right)){
root->right=NULL;
}
if(root->left==NULL && root->right==NULL && root->val==0) return false;
else return true;
}
题解代码(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:
bool dfs(TreeNode* root){
if(root==NULL) return false;
bool l = dfs(root->left);
bool r = dfs(root->right);
if(!l){
root->left=NULL;
}
if(!r){
root->right=NULL;
}
if(root->right==NULL && root->left==NULL && root->val==0) return false;
else return true;
}
TreeNode* pruneTree(TreeNode* root) {
if(root==NULL) return NULL;
if(dfs(root)) return root;
else return NULL;
}
};
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
boolean dfs(TreeNode root){
if(root==null) return false;
if(!dfs(root.left)) root.left=null;
if(!dfs(root.right)) root.right=null;
if(root.left==null && root.right==null && root.val==0) return false;
else return true;
}
public TreeNode pruneTree(TreeNode root) {
if(root==null) return null;
if(dfs(root)) return root;
else return null;
}
}
题解代码(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 dfs(self,root:TreeNode)->bool:
if root is None:
return False
if not self.dfs(root.left):
root.left = None
if not self.dfs(root.right):
root.right = None
if root.left is None and root.right is None and root.val ==0:
return False
else:
return True
def pruneTree(self, root: TreeNode) -> TreeNode:
if root is None:
return None
if self.dfs(root):
return root
else:
return None
实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。
调用 next() 将返回二叉搜索树中的下一个最小的数。
示例:BSTIterator iterator = new BSTIterator(root); iterator.next(); //
返回 3 iterator.next(); // 返回 7 iterator.hasNext(); // 返回 true
iterator.next(); // 返回 9 iterator.hasNext(); // 返回 true
iterator.next(); // 返回 15 iterator.hasNext(); // 返回 true
iterator.next(); // 返回 20 iterator.hasNext(); // 返回 false提示:
next() 和 hasNext() 操作的时间复杂度是 O(1),并使用 O(h) 内存,其中 h 是树的高度。
你可以假设 next()调用总是有效的,也就是说,当调用 next() 时,BST 中至少存在一个下一个最小的数。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-search-tree-iterator
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:本题是一个设计类的题,使用的是二叉搜索树的结构,调用next()函数来返回下一个最小的值,调用hasNext()来判断是否还有值。
并且题目说了,next() 和 hasNext() 操作的时间复杂度是 O(1),并使用 O(h) 内存。
也就是说,先遍历一遍把所有结果放到一个数组里,然后迭代输出,这种方法虽然简便,但是违反了设计理念,这就退化成输出一个数组了。
一个迭代器对象最主要的一点就是所需的空间要小,而且取数据操作时间复杂度为O(1)。
在二叉树的遍历中,之前使用的都是递归的方法,下面简单介绍一下非递归的方法,本题就靠这个非递归的方法了。
首先,递归的调用隐式地使用了栈的数据结构,既然要用非递归实现,那么一个栈是必不可少的,而且在遍历过程中,栈所需的空间最多达到h(树高)。
1、根据中序遍历,首先是要找到第一个访问的结点,第一个访问的结点是什么样的结点呢?一定是根节点root的左孩子的左孩子的…的左孩子,直到某个结点的左孩子为空,期间一直在压栈。(可以回顾中序遍历递归的代码)
2、如上图所示:不断迭代找到第一访问的结点,并且期间不断压栈。
3、当出现了某个结点左孩子为空的时候,说明已经找到要访问的结点了,就被压在栈顶,只需要取出来然后访问即可。
4、访问完某个结点后,然后就是看它的右孩子,如果不为空依然是压栈,继续找到左孩子为空的结点。
5、如果在第4步发现右孩子为空,那么就访问栈顶元素吧,栈顶元素一定是父节点,因为按次序压栈的嘛。(语言叙述不是很给力,建议自己画图推导推导)
6、如果把栈的元素清空了,那么就相当于递归完毕,那就是遍历结束。
非递归中序遍历二叉树的框架:
void inorder(TreeNode* root,vector<int> &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;
}
}
}
本题借助非递归中序遍历二叉树来解决问题。
题解代码(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 BSTIterator {
public:
stack<TreeNode*> s;
BSTIterator(TreeNode* root) {
//先迭代找到第一个要访问的结点
while(root){
s.push(root);
root = root->left;
}
}
/** @return the next smallest number */
int next() {
TreeNode* temp = s.top();s.pop();
int res = temp->val;
temp = temp->right;
while(temp){
s.push(temp);
temp = temp->left;
}
return res;
}
/** @return whether we have a next smallest number */
bool hasNext() {
return !s.empty();
}
};
/**
* Your BSTIterator object will be instantiated and called as such:
* BSTIterator* obj = new BSTIterator(root);
* int param_1 = obj->next();
* bool param_2 = obj->hasNext();
*/
题解代码(Java):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class BSTIterator {
Stack<TreeNode> s = new Stack<>();
public BSTIterator(TreeNode root) {
while(root!=null){
this.s.push(root);
root = root.left;
}
}
/** @return the next smallest number */
public int next() {
TreeNode temp = this.s.pop();
int res = temp.val;
temp = temp.right;
while(temp!=null){
this.s.push(temp);
temp = temp.left;
}
return res;
}
/** @return whether we have a next smallest number */
public boolean hasNext() {
return this.s.size()>0;
}
}
/**
* Your BSTIterator object will be instantiated and called as such:
* BSTIterator obj = new BSTIterator(root);
* int param_1 = obj.next();
* boolean param_2 = obj.hasNext();
*/
题解代码(Python):
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class BSTIterator:
def __init__(self, root: TreeNode):
self.s = []
while root:
self.s.append(root)
root = root.left
def next(self) -> int:
"""
@return the next smallest number
"""
temp = self.s.pop()
res = temp.val
temp = temp.right
while temp is not None:
self.s.append(temp)
temp = temp.left
return res
def hasNext(self) -> bool:
"""
@return whether we have a next smallest number
"""
return len(self.s)>0
# Your BSTIterator object will be instantiated and called as such:
# obj = BSTIterator(root)
# param_1 = obj.next()
# param_2 = obj.hasNext()
返回与给定先序遍历 preorder 相匹配的二叉搜索树(binary search tree)的根结点。
(回想一下,二叉搜索树是二叉树的一种,其每个节点都满足以下规则,对于 node.left 的任何后代,值总 < node.val,而node.right 的任何后代,值总 node.val。此外,先序遍历首先显示节点的值,然后遍历 node.left,接着遍历 node.right。)
示例:
输入:[8,5,1,7,10,12] 输出:[8,5,10,1,7,null,12]
提示:
1 <= preorder.length <= 100 先序 preorder 中的值是不同的。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/construct-binary-search-tree-from-preorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路解析:注意要看题目:返回与给定先序遍历 preorder 相匹配的二叉搜索树。
如果光是有先序遍历的preorder,而没有二叉搜索树的限制,最简单的就是不断加左孩子结点或者是右孩子结点,都退化成链表了。
言归正传,既然是二叉搜索树,其中序遍历的结果是一个升序的数组,学过数据结构的都知道,知道先序遍历和中序遍历的结果,就可以确定唯一一棵二叉树。
所以本题隐式地提醒我们,要排序,得到中序遍历结果,然后根据先序中序遍历结果构建树。
也可以不用排序,思路2:
先序遍历的第一个元素肯定是根节点,然后要根据二叉搜索树的特性,比根节点小的在左子树,比根节点大的在右子树,需要把先序遍历的元素分为两部分,然后可以递归构造树了。
题解代码(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* bstFromPreorderHelper(vector<int>& preorder,int l,int r){
if(l>r) return NULL;
TreeNode* root = new TreeNode(preorder[l]);
int index = l+1;
for(;index<=r;index++) if(preorder[l]<preorder[index]) break;
root->left = bstFromPreorderHelper(preorder,l+1,index-1);
root->right = bstFromPreorderHelper(preorder,index,r);
return root;
}
TreeNode* bstFromPreorder(vector<int>& preorder) {
if(preorder.size()==0) return NULL;
else return bstFromPreorderHelper(preorder,0,preorder.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 {
public TreeNode bstFromPreorderHelper(int[] preorder,int l,int r){
if(l>r) return null;
TreeNode root = new TreeNode(preorder[l]);
int index = l+1;
for(;index<=r;index++) if(preorder[l]<preorder[index]) break;
root.left = bstFromPreorderHelper(preorder,l+1,index-1);
root.right = bstFromPreorderHelper(preorder,index,r);
return root;
}
public TreeNode bstFromPreorder(int[] preorder) {
if(preorder.length==0) return null;
else return bstFromPreorderHelper(preorder,0,preorder.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 bstFromPreorderHelper(self,preorder:List[int],l:int,r:int) ->TreeNode:
if l>r:
return None
root = TreeNode(preorder[l])
index = l+1
while index<=r:
if preorder[l]<preorder[index]:
break;
index+=1
root.left = self.bstFromPreorderHelper(preorder,l+1,index-1)
root.right = self.bstFromPreorderHelper(preorder,index,r)
return root
def bstFromPreorder(self, preorder: List[int]) -> TreeNode:
if len(preorder) ==0 :
return None
else:
return self.bstFromPreorderHelper(preorder,0,len(preorder)-1)