二叉树的双指针
判断两颗树是否相同
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null){
return true;
}else if(p==null&&q!=null||p!=null&&q==null){
return false;
}
LinkedList<TreeNode> queue1=new LinkedList<>();
LinkedList<TreeNode> queue2=new LinkedList<>();
queue1.offer(p);
queue2.offer(q);
while (!queue1.isEmpty()&&!queue2.isEmpty()){
int size1 = queue1.size();
int size2 = queue2.size();
if(size1!=size2) return false;
for (int i = 0; i < size1; i++) {
TreeNode node1 = queue1.poll();
TreeNode node2 = queue2.poll();
if(node1.val!=node2.val) return false;
if(node1.left!=null&&node2.left!=null){
queue1.offer(node1.left);
queue2.offer(node2.left);
}else if(node1.left==null&&node2.left==null){
}else {
return false;
}
if(node1.right!=null&&node2.right!=null){
queue1.offer(node1.right);
queue2.offer(node2.right);
}else if(node1.right==null&&node2.right==null){
}else {
return false;
}
}
}
return queue1.isEmpty()&&queue2.isEmpty()?true:false;
}
}
class Solution1 {
public boolean isSameTree(TreeNode p, TreeNode q) {
if(p==null&&q==null) return true;
if(p==null||q==null) return false;
if(p.val!=q.val) return false;
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
}
对称二叉树
class Solution {
public boolean isSymmetric(TreeNode root) {
if(root==null) return true;
TreeNode left=root.left;
TreeNode right=root.right;
return isAlike( left,right);
}
private boolean isAlike(TreeNode left, TreeNode right) {
if(left==null&&right==null) return true;
if(right==null||left==null) return false;
if(left.val!=right.val) return false;
return isAlike(left.left,right.right)&&isAlike(left.right,right.left);
}
}
合并二叉树
class Solution {
public static void main(String[] args) {
TreeNode root1=new TreeNode(1);
TreeNode root2=new TreeNode(1,new TreeNode(2),null);
mergeTrees(root1,root2);
}
public static TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1==null&&root2==null) return null;
if(root1==null||root2==null) {
return root1==null?root2:root1;
}
TreeNode root=new TreeNode(root1.val+root2.val);
TreeNode left=mergeTrees(root1.left,root2.left);
TreeNode right=mergeTrees(root1.right,root2.right);
root.left=left;
root.right=right;
return root;
}
}
路径专题
二叉树的所有路径
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res=new ArrayList<>();
StringBuilder sb=new StringBuilder();
if(root==null) return res;
addToRes(res,root,sb);
return res;
}
private void addToRes(List<String> res, TreeNode root, StringBuilder sb) {
if(sb.length()==0){
sb.append(root.val);
}else {
sb.append("->"+root.val);
}
if(root.left==null&&root.right==null){
res.add(sb.toString());
return;
}
StringBuilder sbb=new StringBuilder(sb);
if(root.left!=null) {
addToRes(res,root.left,sbb);
}
sbb=new StringBuilder(sb);
if(root.right!=null){
addToRes(res,root.right,sbb);
}
}
}
class Solution {
public static void main(String[] args) {
TreeNode treeNode=new TreeNode(1,new TreeNode(2),null);
binaryTreePaths(treeNode);
}
public static List<String> binaryTreePaths(TreeNode root) {
List<String> res=new ArrayList<>();
if(root==null) return res;
addToRes(res,root,"");
return res;
}
private static void addToRes(List<String> res, TreeNode root, String path) {
if(root==null) return;
if(root.left==null&&root.right==null) {
res.add(path+root.val);
return;
}
addToRes(res,root.left,path+root.val+"->");
addToRes(res,root.right,path+root.val+"->");
}
}
路径总和
class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
int sum=0;
if(root==null) return false;
return dp(root,sum,targetSum);
}
private boolean dp(TreeNode root, int sum, int targetSum) {
if(root==null&&sum==targetSum) return true;
if(root==null&&sum!=targetSum) return false;
sum+=root.val;
if(root.left!=null&&root.right!=null){
return dp(root.left,sum,targetSum)||dp(root.right,sum,targetSum);
}else if(root.right!=null){
return dp(root.right,sum,targetSum);
}else {
return dp(root.left,sum,targetSum);
}
}
}
翻转的妙用
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) return null;
TreeNode left = invertTree(root.left);
TreeNode right = invertTree(root.right);
root.left = right;
root.right = left;
return root;
}
}
最大深度问题
最大深度问题 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:3
class Solution {
public int maxDepth(TreeNode root) {
if(root==null) return 0;
return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}
}
class Solution1 {
public int maxDepth(TreeNode root) {
if(root==null) return 0;
LinkedList<TreeNode> queue=new LinkedList<>();
int dep=0;
queue.offer(root);
while (!queue.isEmpty()){
dep++;
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if(node.right!=null) queue.offer(node.right);
if(node.left!=null) queue.offer(node.left);
}
}
return dep;
}
}
判断平衡树
平衡二叉树 给定一个二叉树,判断它是否是高度平衡的二叉树。 本题中,一棵高度平衡二叉树定义为: 一个二叉树_每个节点 _的左右两个子树的高度差的绝对值不超过 1 。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:true
class Solution {
public boolean isBalanced(TreeNode root) {
if(root==null) return true;
int lenLeft= getDep(root.left);
int lenRight= getDep(root.right);
return Math.abs(lenLeft-lenRight)<=1&&isBalanced(root.right)&&isBalanced(root.left);
}
private int getDep(TreeNode root) {
if(root==null) return 0;
return Math.max(getDep(root.left),getDep(root.right))+1;
}
}
:::info 解题思路 求节点的高度: 求出左右节点的高度:如果=-1就放回-1 如果左右高度差>1返回-1 结果不为-1就是平衡二叉树 :::
class Solution1 {
public boolean isBalanced(TreeNode root) {
int ans=getHeight(root);
return ans==-1?false:true;
}
private int getHeight(TreeNode node) {
if(node==null) return 0;
int leftHeight = getHeight(node.left);
if(leftHeight==-1) return -1;
int rightHeight = getHeight(node.right);
if(rightHeight==-1) return -1;
return Math.abs(leftHeight-rightHeight)<=1?Math.max(leftHeight,rightHeight)+1:-1;
}
}
最小深度
二叉树的最小深度 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 **说明:**叶子节点是指没有子节点的节点。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:2
:::info 层序遍历: 压住队列中:如果队列中有元素没有子节点,说明就是最小深度 :::
class Solution1 {
public int minDepth(TreeNode root) {
if(root==null) return 0;
LinkedList<TreeNode> queue=new LinkedList<>();
int res=1;
queue.offer(root);
boolean flag=true;
while (!queue.isEmpty()&&flag){
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
if(node.left==null&&node.right==null) flag=false;
if(node.left!=null) queue.offer(node.left);
if(node.right!=null) queue.offer(node.right);
}
res++;
}
return res-1;
}
}
:::info 递归 :::
class Solution {
public int minDepth(TreeNode root) {
if(root==null) return 0;
if(root.left==null) return minDepth(root.right)+1;
if(root.right==null) return minDepth(root.left)+1;
return Math.min(minDepth(root.left),minDepth(root.right))+1;
}
}
N叉树的最大深度
N叉树的最大深度 给定一个 N 叉树,找到其最大深度。 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。 N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6] 输出:3
class Solution {
public int maxDepth(Node root) {
if(root==null) return 0;
int max=0;
for (Node child : root.children) {
int dep = maxDepth(child);
if(dep>max) max=dep;
}
return max+1;
}
}
最近公共祖先问题
二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 输出:3 解释:节点 5 和节点 1 的最近公共祖先是节点 3 。
示例 2:
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 输出:5 解释:节点 5 和节点 4 的最近公共祖先是节点 5 。因为根据定义最近公共祖先节点可以为节点本身。
class Solution {
public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null) return null;
List<TreeNode> containP=new ArrayList<>();
List<TreeNode> containQ=new ArrayList<>();
List<TreeNode> list1 = getContainNodeList(containP, root, p);
List<TreeNode> list2 = getContainNodeList(containQ, root, q);
for (int i = list1.size()-1; i >=0; i--) {
TreeNode treeNode = list1.get(i);
if(list2.contains(treeNode)){
return treeNode;
}
}
return null;
}
private static List<TreeNode> getContainNodeList(List<TreeNode> list, TreeNode root, TreeNode node) {
if(root==null) return list;
list.add(root);
List<TreeNode> listL=new ArrayList<>(list);
if(root==node) return list;
List<TreeNode> list1 = getContainNodeList(list, root.left, node);
if(list1.contains(node)) return list1;
List<TreeNode> list2 = getContainNodeList(listL, root.right, node);
return list2;
}
}
public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root==null) return root;
if(root==p||root==q) return root;
TreeNode left=lowestCommonAncestor(root.left,p,q);
TreeNode right=lowestCommonAncestor(root.right,p,q);
if(left!=null&&right!=null) return root;
if(right==null&&left==null) return null;
if(left==null) return right;
if(right==null) return left;
return null;
}