6.偶数个结点:n1=1;奇数个结点n1=0
相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。
如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
示例 1:
输入:p = [1,2,3], q = [1,2,3]
输出:true
示例 2:
输入:p = [1,2], q = [1,null,2]
输出:false
思路:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p!=null&&q==null||p==null&&q!=null){
return false;
}
if(p==null&&q==null){
return true;
}
//p\q都不为null
if(p.val!=q.val){
return false;
}
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
}
另一棵树的子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。
二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。
示例 1:
输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true
示例 2:
输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false
思路:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSubtree(TreeNode root, TreeNode subRoot) {
if(root==null||subRoot==null){
return false;
}
if(isSameTree(root,subRoot)) return true;
if(isSubtree(root.left,subRoot)) return true;
if(isSubtree(root.right,subRoot)) return true;
return false;
}
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p!=null&&q==null||p==null&&q!=null){
return false;
}
if(p==null&&q==null){
return true;
}
//p\q都不为null
if(p.val!=q.val){
return false;
}
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
}
平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:true
示例 2:
输入:root = [1,2,2,3,3,null,null,4,4]
输出:false
示例 3:
输入:root = []
输出:true
思路:
平衡:每棵子树左右高度差不能超过1
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isBalanced(TreeNode root) {
return maxDepth(root)>=0;
}
public int maxDepth(TreeNode root){
if(root==null){
return 0;
}
int leftH=maxDepth(root.left);
int leftR=maxDepth(root.right);
//一个结点左右子树遍历完
if(leftH>=0&&leftR>=0&&Math.abs(leftH-leftR)<=1){
return Math.max(leftH,leftR)+1;
}else{
return -1;//说明不平衡
}
}
}
给你一个二叉树的根节点 root , 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3]
输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3]
输出:false
思路:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null){
return true;
}
//判断左树右树是不是对称的
return isSymmetricChild(root.left,root.right);
}
public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree){
//1.一个为空,一个不为空
if(leftTree==null&&rightTree!=null||leftTree!=null&&rightTree==null){
return false;
}
//2.两个都为空
if(leftTree==null&&rightTree==null){
return true;
}
//3.值是不是一样的
if(leftTree.val==rightTree.val){
return isSymmetricChild(leftTree.left,rightTree.right)&&isSymmetricChild(leftTree.right,rightTree.left);
}
return false;
}
}
思路:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null){
return null;
}
if(root==p||root==q){
return root;
}
TreeNode leftTree=lowestCommonAncestor(root.left,p,q);
TreeNode rightTree=lowestCommonAncestor(root.right,p,q);
if(leftTree!=null&&rightTree!=null){
return root;
}
if(leftTree!=null&&rightTree==null){
return leftTree;
}
if(leftTree==null&&rightTree!=null){
return rightTree;
}
return null;
}
}
1.还可以使用 两个链表求交点(p到公共祖先、q到公共祖先看作两个链表),但前提是每个节点需包含parent域。
2.利用栈,从root节点到p的所有节点插入栈1中,从root节点到q的所有节点放入栈2中,根据栈1和栈2中size的差值,将栈元素数量多的栈元素弹出,直到两个栈中元素数量一致;然后栈1和栈2同时弹出元素,直到弹出的元素相等,即为 【最近公共祖先】
描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示
数据范围:输入二叉树的节点数 0≤n≤1000,二叉树中每个节点的值 0≤val≤1000
要求:空间复杂度O(1)(即在原树上操作),时间复杂度 O(n)
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeNode prev=null;
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null){
return null;
}
ConvertChild(pRootOfTree);
TreeNode head=pRootOfTree;
while(head.left!=null){
head=head.left;
}
return head;
}
public void ConvertChild(TreeNode pCur){
if(pCur==null){
return ;
}
ConvertChild(pCur.left);
pCur.left=prev;
if(prev!=null){
prev.right=pCur;
}
prev=pCur;
ConvertChild(pCur.right);
}
}
从前序与中序遍历序列构造二叉树
关键在于通过preorder得知根结点,在inorder 中找到根节点下标,以此划分左右子树,再根据左右子树下标区间进行递归,来构造二叉树。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int preIndex=0;
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTreeChild(preorder,inorder,0,inorder.length-1);
}
public TreeNode buildTreeChild(int[] preorder,int[] inorder,int inbegin,int inend){
if(inbegin>inend){
return null;//说明没有左树 或者 没有右树
}
TreeNode root=new TreeNode(preorder[preIndex]);
int rootIndex=findIndex(inorder,preorder[preIndex],inbegin,inend);
preIndex++;
root.left=buildTreeChild(preorder,inorder,inbegin,rootIndex-1);
root.right=buildTreeChild(preorder,inorder,rootIndex+1,inend);
return root;
}
public int findIndex(int[] inorder,int key,int inbegin,int inend){
for(int i=inbegin;i<=inend;i++){
if(inorder[i]==key){
return i;
}
}
return -1;
}
}
同理106. 从中序与后序遍历序列构造二叉树
从中序与后序遍历序列构造二叉树
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int postIndex=0;
public TreeNode buildTree(int[] inorder, int[] postorder) {
postIndex=postorder.length-1;
return buildTreeChild(inorder,0,inorder.length-1,postorder);
}
public TreeNode buildTreeChild(int[] inorder,int inbegin,int inend,int[] postorder){
if(inbegin>inend){
return null;
}
TreeNode root=new TreeNode(postorder[postIndex]);
int rootIndex=findIndex(inorder,inbegin,inend,postorder[postIndex]);
postIndex--;
root.right=buildTreeChild(inorder,rootIndex+1,inend,postorder);
root.left=buildTreeChild(inorder,inbegin,rootIndex-1,postorder);
return root;
}
public int findIndex(int[] inorder,int inbegin,int inend,int key){
for(int i=inbegin;i<=inend;i++){
if(inorder[i]==key){
return i;
}
}
return -1;
}
}
给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。
空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。
空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。
示例 1:
输入:root = [1,2,3,4]
输出:“1(2(4))(3)”
解释:初步转化后得到 “1(2(4)())(3()())” ,但省略所有不必要的空括号对后,字符串应该是"1(2(4))(3)" 。
示例 2:
输入:root = [1,2,3,null,4]
输出:“1(2()(4))(3)”
解释:和第一个示例类似,但是无法省略第一个空括号对,否则会破坏输入与输出一一映射的关系。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public String tree2str(TreeNode root) {
StringBuilder sb=new StringBuilder();
if(root==null){
return sb.toString();
}
tree2strChild(root,sb);
return new String(sb);
}
public void tree2strChild(TreeNode t,StringBuilder sb){
if(t==null){
return ;
}
sb.append(t.val);//根 左 右
if(t.left!=null){
sb.append("(");
tree2strChild(t.left,sb);
sb.append(")");
}else{
if(t.right==null){
return;
}else{
sb.append("()");
}
}
if(t.right==null){
return;
}else{
sb.append("(");
tree2strChild(t.right,sb);
sb.append(")");
}
}
}