1、NC117 合并二叉树
public TreeNode mergeTrees (TreeNode t1, TreeNode t2)
public class Solution {
/**
*
* @param t1 TreeNode类
* @param t2 TreeNode类
* @return TreeNode类
*/
public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {
if (t1 == null && t2 == null) return null;
if (t1 == null || t2 == null) return t1 == null ? t2 : t1;
// 此时 t1、t2 均不为 null
// 合并节点的值
t1.val = t1.val + t2.val;
// 合并左子树
t1.left = mergeTrees(t1.left, t2.left);
// 合并右子树
t1.right = mergeTrees(t1.right, t2.right);
return t1;
}
}
2、NC161 二叉树的中序遍历
public int[] inorderTraversal (TreeNode root)
解法1:递归
public class Solution {
// 中序遍历的递归写法 思路清晰但是不够高效
ArrayList<Integer> list = new ArrayList<>();
public int[] inorderTraversal (TreeNode root) {
recur(root);
return list.stream().mapToInt(Integer::valueOf).toArray();
}
public void recur(TreeNode root) {
if (root == null) return;
recur(root.left);
list.add(root.val);
recur(root.right);
}
}
解法2:非递归(往左找,出栈往右找)
public int[] inorderTraversal (TreeNode root) {
ArrayList<Integer> arrList=new ArrayList<>();
Stack<TreeNode> stack=new Stack<>();
while(root!=null || !stack.isEmpty()){
while(root!=null){
stack.push(root);
root=root.left;
}
root=stack.pop();
arrList.add(root.val);
root=root.right;
}
return arrList.stream().mapToInt(Integer::valueOf).toArray();
}
3、NC72 二叉树的镜像
public TreeNode Mirror (TreeNode pRoot)
public TreeNode Mirror (TreeNode pRoot) {
if(pRoot == null) {
return null;
}
if(pRoot.left == null && pRoot.right == null) {
return pRoot;
}
TreeNode L = Mirror(pRoot.left);
TreeNode R = Mirror(pRoot.right);
pRoot.left = R;
pRoot.right = L;
return pRoot;
}
4、NC13 二叉树的最大深度
public int maxDepth (TreeNode root)
解法1:非递归-层次遍历+队列
public int maxDepth (TreeNode root) {
//通过层次遍历计算二叉树的深度
if(root==null) return 0;
Queue<TreeNode>queue=new LinkedList<>();
queue.offer(root);
int level=0,size;
while(!queue.isEmpty()){
size=queue.size();
for(int i=0;i<size;i++){
TreeNode node=queue.poll();
if(node.left!=null) queue.offer(node.left);
if(node.right!=null) queue.offer(node.right);
}
level++;
}
return level;
}
解法2:递归
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型
*/
public int maxDepth (TreeNode root) {
if(root==null){
return 0;
}
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return 1 + Math.max(left,right);
}
}
5、NC136 输出二叉树的右视图
public int[] solve (int[] xianxu, int[] zhongxu)
构造出二叉树之后再用队列找到每层的最后一个节点
HashMap<Integer,Integer> inOrderHashMap = new HashMap<>();
public int[] solve (int[] xianxu, int[] zhongxu) {
// write code here
if (xianxu==null||zhongxu==null||xianxu.length==0||zhongxu.length==0) return new int[0];
for (int i = 0; i < zhongxu.length; i++) {
inOrderHashMap.put(zhongxu[i],i);
}
TreeNode root = buildTree(xianxu, 0, xianxu.length - 1, inOrderHashMap, 0, zhongxu.length - 1);
Deque<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
int[] res = new int[xianxu.length];
int count =0;
while (!queue.isEmpty()){
//拿到当前层元素个数
int len = queue.size();
System.out.println(len);
for (int i = 0; i < len; i++) {
TreeNode node = queue.poll();
if (node.left!=null) queue.offer(node.left);
if (node.right!=null) queue.offer(node.right);
//到最后一个元素了
if (i==len-1) res[count++] = node.val;
}
}
//count是有效数组元素 0下标开始 跟左闭右开刚好对冲
return Arrays.copyOfRange(res,0,count);
}
//inOrder: [inLeft,rootIndex-1] rootIndex [rootIndex+1,inRight]
//preOrder: preLeft [preLeft+1,preLeft+rootIndex-inLeft] [preLeft+rootIndex-inLeft+1,preRight]
private TreeNode buildTree(int[] xianxu, int preLeft, int preRight, HashMap<Integer, Integer> inOrderHashMap, int inLeft, int inRight) {
//preLeft == preRight时 也要执行的 --叶子节点罢了
if (preLeft>preRight||inLeft>inRight) return null;
int rootIndex = inOrderHashMap.get(xianxu[preLeft]);
TreeNode root = new TreeNode(xianxu[preLeft]);
root.left = buildTree(xianxu, preLeft + 1, preLeft + rootIndex - inLeft, inOrderHashMap, inLeft, rootIndex - 1);
root.right = buildTree(xianxu,preLeft+rootIndex-inLeft+1,preRight,inOrderHashMap,rootIndex+1,inRight);
return root;
}
6、NC102 在二叉树中找到两个节点的最近公共祖先
public int lowestCommonAncestor (TreeNode root, int o1, int o2)
public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
// write code here
if(root.val == o1 || root.val == o2){
return root.val;
}
TreeNode treeNode = order(root, o1, o2);
return treeNode.val;
}
public TreeNode order(TreeNode root, int o1, int o2){
if(root == null)
return null;
if(root.val == o1 || root.val == o2)
return root;
TreeNode left = order(root.left, o1, o2);
TreeNode right = order(root.right, o1, o2);
if(left != null && right != null)
return root;
if(left == null && right == null)
return null;
return left == null? right: left;
}
7、NC15 求二叉树的层序遍历
public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root)
方法:队列
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
// write code here
if (root == null) {
return new ArrayList<>();
}
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
ArrayList<Integer> temp = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
Queue<TreeNode> mid = new LinkedList<>();
while(!queue.isEmpty()) {
TreeNode node = queue.poll();
temp.add(node.val);
if (node.left != null) {
mid.add(node.left);
}
if (node.right != null) {
mid.add(node.right);
}
if (queue.isEmpty()) {
queue = mid;
mid = new LinkedList<>();
res.add(temp);
temp = new ArrayList<>();
}
}
return res;
}
}
8、NC45 实现二叉树先序、中序、后序遍历
public int[][] threeOrders (TreeNode root)
解法1:递归
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类 the root of binary tree
* @return int整型二维数组
*/
public int[][] threeOrders (TreeNode root) {
if(root==null){
return new int[0][0];
}
int[][] res = new int[3][];
//先序
List<Integer> list1 = new ArrayList<Integer>();
first(root,list1);
res[0] = list1.stream().mapToInt(Integer::intValue).toArray();
//中序
List<Integer> list2 = new ArrayList<Integer>();
second(root,list2);
res[1] = list2.stream().mapToInt(Integer::intValue).toArray();
//后序
List<Integer> list3 = new ArrayList<Integer>();
third(root,list3);
res[2] = list3.stream().mapToInt(Integer::intValue).toArray();
return res;
}
private void first(TreeNode root,List<Integer> list){
if(root==null){
return;
}
list.add(root.val);
first(root.left,list);
first(root.right,list);
}
private void second(TreeNode root,List<Integer> list){
if(root==null){
return;
}
second(root.left,list);
list.add(root.val);
second(root.right,list);
}
private void third(TreeNode root,List<Integer> list){
if(root==null){
return;
}
third(root.left,list);
third(root.right,list);
list.add(root.val);
}
方法2:非递归
/**
* 使用非递归的方法解决
* @param root
* @return
*/
public int[][] threeOrders (TreeNode root) {
if(root==null){
return new int[0][0];
}
List<Integer> list1=new ArrayList<>();
List<Integer> list2=new ArrayList<>();
List<Integer> list3=new ArrayList<>();
preOrder(list1,root);
midOrder(list2,root);
afterOrder(list3,root);
int len = list1.size();
int[][] res=new int[3][len];
for (int i = 0; i < len; i++) {
res[0][i]=list1.get(i);
}
for (int i = 0; i < len; i++) {
res[1][i]=list2.get(i);
}
for (int i = 0; i < len; i++) {
res[2][i]=list3.get(i);
}
return res;
}
/**
* 先序遍历
* @param list1
* @param root
*/
private void preOrder(List<Integer> list1, TreeNode root) {
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
list1.add(node.val);
if(node.right!=null){
stack.push(node.right);
}
if(node.left!=null){
stack.push(node.left);
}
}
}
/**
* 中序遍历
* @param list2
* @param root
*/
private void midOrder(List<Integer> list2, TreeNode root) {
Stack<TreeNode> stack=new Stack<>();
while (!stack.isEmpty() || root!=null){
while (root!=null){
stack.push(root);
root=root.left;
}
TreeNode node = stack.pop();
list2.add(node.val);
if(node.right!=null){
root=node.right;
}
}
}
/**
* 后序遍历
* @param list3
* @param root
*/
private void afterOrder(List<Integer> list3, TreeNode root) {
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while (!stack.isEmpty()){
TreeNode node = stack.pop();
list3.add(node.val);
if(node.left!=null){
stack.push(node.left);
}
if(node.right!=null){
stack.push(node.right);
}
}
Collections.reverse(list3);
}
9、判断二叉树是否对称
public boolean isSymmetric (TreeNode root)
方法1:递归
public class Solution {
public boolean isSymmetric (TreeNode root) {
if (root == null) return true;
return recur(root.left, root.right);
}
// 递归辅助函数
public boolean recur(TreeNode left, TreeNode right) {
if (left == null && right == null) return true;
else if (left != null && right == null) return false;
else if (left == null && right != null) return false;
else return left.val == right.val && recur(left.left, right.right) && recur(left.right, right.left);
}
}
方法2:层次遍历-Deque
public boolean isSymmetric (TreeNode root) {
if (root == null) return true;
Deque<TreeNode> queue = new LinkedList<>();
queue.addLast(root.left);
queue.addLast(root.right);
while (!queue.isEmpty()) {
TreeNode left = queue.pollLast();
TreeNode right = queue.pollLast();
if (left == null && right == null) continue;
if (left == null || right == null) return false;
if (left.val != right.val) return false;
//队列需要添加4个元素
queue.addFirst(left.left);
queue.addFirst(right.right);
queue.addFirst(left.right);
queue.addFirst(right.left);
}
return true;
}
10、NC62 平衡二叉树
public boolean IsBalanced_Solution(TreeNode root)
public class Solution {
private boolean flag;
public boolean IsBalanced_Solution(TreeNode root) {
if(root == null) {
return true;
}
flag = true;
getDepth(root);
return flag;
}
public int getDepth(TreeNode root) {
if(root == null) {
return 0;
}
int L = getDepth(root.left);
int R = getDepth(root.right);
if(Math.abs(L - R) > 1) {
flag = false;
return -1;
}
return Math.max(L, R) + 1;
}
}
或
//平衡二叉树要求:左右子树的深度差不超过1,并且左右子树也是平衡二叉树(空树也可以理解成平衡二叉树)
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root==null) return true;
return (Math.abs(depth(root.left)-depth(root.right))<=1)
&& IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
}
public int depth(TreeNode root){
if(root==null) return 0;
return Math.max(depth(root.left),depth(root.right))+1;
}
}
或
import java.util.*;
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
if(root == null){
return true;
}
//判断两个子树的高度差绝对值是否超过1
if(Math.abs(getTreeDeep(root.left) - getTreeDeep(root.right)) > 1){
return false;
}
return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
}
//计算二叉树的深度
public int getTreeDeep(TreeNode root){
if(root == null){
return 0;
}
int leftNum = 1;
int rightNum = 1;
if(root.left != null){
leftNum += getTreeDeep(root.left);
}
if(root.right != null){
rightNum += getTreeDeep(root.right);
}
return leftNum >= rightNum ? leftNum : rightNum;
}
}
总结:左右子树也要满足&左右子树深度之差不超过1
11、NC9 二叉树中是否存在节点和为指定值的路径---dfs/回溯
public boolean hasPathSum (TreeNode root, int sum)
解法:回溯-结束条件、路径、选择列表
public class Solution {
private ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
ArrayList<Integer> list = new ArrayList<>();
recur(root, sum, list);
return lists;
}
public void recur(TreeNode root, int sum, ArrayList<Integer> list) {
if (root == null) return;
list.add(root.val); // 先加入list中
if (root.left == null && root.right == null) { // 到达叶子结点
if (sum == root.val) lists.add(new ArrayList<Integer>(list));
list.remove(list.size()-1); // 移除当前结点,找到 叶子节点就移除,让list没有叶子节点
} else {
recur(root.left, sum - root.val, list);
recur(root.right, sum - root.val, list);
list.remove(list.size()-1); // 递归返回时移除上一个结点
}
}
}
类似方法
public class Solution {
private ArrayList<ArrayList<Integer>> res;
public void getPath(TreeNode root, int sum, ArrayList<Integer> temp){
if(root == null) return ;
if(root.left == null && root.right == null){
if(sum - root.val == 0){
temp.add(new Integer(root.val));
//注意此处,temp为传入的引用,写入总的记录时候要重新建一个对象,因为后面需要对temp修改。
res.add(new ArrayList<Integer>(temp));
//记录之后,需要回溯temp为上一个状态,继续走右分支。
temp.remove(temp.size()-1);
}
return ;
}
temp.add(new Integer(root.val));
getPath(root.left, sum-root.val, temp);
getPath(root.right, sum-root.val, temp);
//左右分支结束之后需要恢复到上一层递归时候的状态,以便上一层递归选择不同的分支。
temp.remove(temp.size()-1);
}
public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
// write code here
res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> temp = new ArrayList<Integer>();
getPath(root, sum, temp);
return res;
}
}
1
方法1:递归--结束条件,选择列表,路径做选择
public class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null)
return false;
sum -= root.val;
if (sum == 0 && root.left == null && root.right == null)
return true;
return hasPathSum(root.left, sum) || hasPathSum(root.right, sum);
}
}
方法2:dfs
public boolean hasPathSum (TreeNode root, int sum) {
// write code here
return dfs(root,sum);
}
private boolean dfs(TreeNode root, int sum) {
if(root == null) return false;
sum -= root.val;
if(root.left == null && root.right == null && sum == 0) return true;
return dfs(root.left,sum) || dfs(root.right,sum);
}
12、NC5 二叉树根节点到叶子节点的所有路径和---dfs
public int sumNumbers (TreeNode root)
解法1:非递归
private int val = 0;
public int sumNumbers (TreeNode root) {
// write code here
if(root==null)
return 0;
//dfs(root,0);
Stack<TreeNode> st = new Stack<>();//使用栈,将从根节点往下的值依次相加,直到左右子树均为空且栈空,则表示到达最底部。
st.push(root);
while(!st.isEmpty()){
TreeNode p = st.pop();
if(p.left==null && p.right==null){
val = val +p.val; //val计算路径和
}else{
if(p.left!=null){
p.left.val = p.val *10 + p.left.val;
st.push(p.left);
}
if(p.right!=null){
p.right.val = p.val *10 + p.right.val;
st.push(p.right);
}
}
}
return val;
}
方法2:回溯-结束条件 、路径、选择列表
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
private int res = 0;
/**
*
* @param root TreeNode类
* @return int整型
*/
public int sumNumbers (TreeNode root) {
if(root==null){
return 0;
}
process(root,0);
return res;
}
private void process(TreeNode root,int agg){
agg = agg*10 + root.val;
if(root.left==null&&root.right==null){
res = res + agg;
}else{
if(root.left!=null){
process(root.left,agg);
}
if(root.right!=null){
process(root.right,agg);
}
}
}
}
13、NC11 将升序数组转化为平衡二叉搜索树
public TreeNode sortedArrayToBST (int[] num)
解法1:递归&选择中间的作为根节点
public class Solution22 {
public TreeNode sortedArrayToBST(int[] num) {
if(num==null||num.length==0)
return null;
return sorted(num,0,num.length-1);
}
public TreeNode sorted(int[] num,int left,int right) {
if(left>right)
return null;
int mid =(left+right+1)/2;
int num1 =num[mid];
TreeNode node = new TreeNode(num1);
node.left =sorted(num,left,mid-1);
node.right = sorted(num,mid+1,right);
return node;
}
}
14、NC8 二叉树根节点到叶子节点和为指定值的路径
public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum)
解法:回溯-结束条件、路径、选择列表
public class Solution {
private ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
ArrayList<Integer> list = new ArrayList<>();
recur(root, sum, list);
return lists;
}
public void recur(TreeNode root, int sum, ArrayList<Integer> list) {
if (root == null) return;
list.add(root.val); // 先加入list中
if (root.left == null && root.right == null) { // 到达叶子结点
if (sum == root.val) lists.add(new ArrayList<Integer>(list));
list.remove(list.size()-1); // 移除当前结点,找到 叶子节点就移除,让list没有叶子节点
} else {
recur(root.left, sum - root.val, list);
recur(root.right, sum - root.val, list);
list.remove(list.size()-1); // 递归返回时移除上一个结点
}
}
}
类似方法
public class Solution {
private ArrayList<ArrayList<Integer>> res;
public void getPath(TreeNode root, int sum, ArrayList<Integer> temp){
if(root == null) return ;
if(root.left == null && root.right == null){
if(sum - root.val == 0){
temp.add(new Integer(root.val));
//注意此处,temp为传入的引用,写入总的记录时候要重新建一个对象,因为后面需要对temp修改。
res.add(new ArrayList<Integer>(temp));
//记录之后,需要回溯temp为上一个状态,继续走右分支。
temp.remove(temp.size()-1);
}
return ;
}
temp.add(new Integer(root.val));
getPath(root.left, sum-root.val, temp);
getPath(root.right, sum-root.val, temp);
//左右分支结束之后需要恢复到上一层递归时候的状态,以便上一层递归选择不同的分支。
temp.remove(temp.size()-1);
}
public ArrayList<ArrayList<Integer>> pathSum (TreeNode root, int sum) {
// write code here
res = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> temp = new ArrayList<Integer>();
getPath(root, sum, temp);
return res;
}
}
15、NC6 二叉树的最大路径和
public int maxPathSum (TreeNode root)
解法:回溯-结束条件,记录路径,做选择
public class Solution {
/**
*
* @param root TreeNode类
* @return int整型
*/
public int maxPathSum (TreeNode root) {
// write code here
if(root == null){return 0;}
int[] res = {0x80000000};
subTreeMax(root, res);
return res[0];
}
private int subTreeMax(TreeNode root, int[] res){
// subTreeMax()函数 1.计算包含子树根节点root的最大非折返路径和。
// 所谓非折返,就是路径不能同时包含左右子树。折返路径就是左子树+root+右子树
// 2. 根据最大折返路径与最大非折返路径更新最大路径和。
if(root == null){return 0;}
int leftMax = subTreeMax(root.left, res);
int rightMax = subTreeMax(root.right, res);
int childMax = Math.max(leftMax, rightMax);
int ret = childMax > 0? childMax + root.val: root.val;
int leftRootRight = leftMax + root.val + rightMax;
res[0] = Math.max(res[0], Math.max(leftRootRight, ret));//避免有负的
return ret;
}
}
16、NC60 判断一棵二叉树是否为搜索二叉树
public boolean[] judgeIt (TreeNode root)
解法:回溯
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类 the root
* @return bool布尔型一维数组
*/
boolean searchFlag= true;
boolean completeFlag = true;
int num=Integer.MIN_VALUE;
Stack<Integer> stack = new Stack<>();
public boolean[] judgeIt (TreeNode root) {
dfs(root,0);
return new boolean[]{searchFlag, completeFlag};
}
public void dfs(TreeNode root, int len) {
//如果两者为false,则开始剪枝
if(!searchFlag && !completeFlag) return ;
if(root==null){
//判断是否是完全二叉树:
//如果是完全二叉树,那么每个空子叶节点所在路径长度差值不得大于1,并且左子节点路径长度必须大于等于右子节点路径长度
//当节点为空说明是一个空子叶节点,此时将该路径长度与前一个路径(上一个空子节点路径)的长度做比较,如果大于则不是完全二叉树
if(stack.size()>=1 && stack.peek()<len) completeFlag=false;
stack.add(len);
return ;
}
dfs(root.left, len+1);
//判断是否是搜索二叉树:
//如果是搜索二叉树,那么中序遍历的结果应该是递增关系。
//如果此访问节点值小于上一个访问节点值,说明破坏了递增规律,则不是搜索二叉树。
if(root.val>=num){
num = root.val;
}else {
searchFlag=false;
}
dfs(root.right,len+1);
}
}
其他
import java.util.*;
/*
* public class TreeNode {
* int val = 0;
* TreeNode left = null;
* TreeNode right = null;
* }
*/
public class Solution {
/**
*
* @param root TreeNode类 the root
* @return bool布尔型一维数组
*/
long pre = Long.MIN_VALUE;
public boolean[] judgeIt (TreeNode root) {
// write code here
return new boolean[]{isSBT(root),isCBT(root)};
}
/**
* 判断一棵二叉树是否为搜索二叉树,只要改写一个二叉树中序遍历,在遍历的过程中看节点值是否都是递增的即可。
* @param root
* @return
*/
public boolean isSBT(TreeNode root) {
if (root == null) {
return true;
}
if(!isSBT(root.left)) {
return false;
}
if (root.val <= pre) {
return false;
}
pre = root.val;
return isSBT(root.right);
}
/**
*
* 判断一棵二叉树是否为完全二叉树,依据以下标准会使判断过程变得简单且易实现。
* 1.按层遍历二叉树,从每层的左边向右边依次遍历所有的节点。
* 2.如果当前节点有右孩子节点,但没有左孩子节点,则直接返回 false。
* 3.如果当前节点并不是左右孩子节点全有,那么之后的节点必须都为叶节点,否则返回false。
* 4.遍历过程中如果不返回 false,则遍历结束后返回 true。
* @param root
* @return
*/
public boolean isCBT(TreeNode root) {
if (root == null) {
return true;
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean leaf = false;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
//如果当前节点并不是左右孩子节点全有,那么之后的节点必须都为叶节点
if (leaf && (node.left != null || node.right != null)) {
return false;
}
//如果当前节点有右孩子节点,但没有左孩子节点,则直接返回 false
if (node.left == null && node.right != null) {
return false;
}
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
} else {
leaf = true;
}
}
}
return true;
}
}
17、NC12 重建二叉树
public TreeNode reConstructBinaryTree(int [] pre,int [] in)
解法1:
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
//前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
if(startPre>endPre||startIn>endIn)
return null;
TreeNode root=new TreeNode(pre[startPre]);
for(int i=startIn;i<=endIn;i++)
if(in[i]==pre[startPre]){
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
break;
}
return root;
}
}
类似:
public class Solution {
int i = 0;
public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {
if(i == pre.length && vin.length == 0) return null;
TreeNode root = null;
for(int j = 0; j < vin.length; j++) {
if(pre[i] == vin[j]) {
root = new TreeNode(pre[i]);
i++;
root.left = reConstructBinaryTree(pre,Arrays.copyOfRange(vin,0,j));
root.right = reConstructBinaryTree(pre,Arrays.copyOfRange(vin,j+1,vin.length));
break;
}
}
return root;
}
}
18、NC14 按之字形顺序打印二叉树
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot)
import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
import java.util.Collections;
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > res =new ArrayList<>();
if(pRoot == null){
return res;
}
Queue<TreeNode> queue =new LinkedList<TreeNode>();
queue.offer(pRoot);
boolean b = true;
while(!queue.isEmpty()){
int num = queue.size();
ArrayList<Integer> temp = new ArrayList<>();
for(int i = 0;i< num;i++){
TreeNode t = queue.poll();
if(t.left != null){
queue.offer(t.left);
}
if(t.right != null){
queue.offer(t.right);
}
temp.add(t.val);
}
if(!b){
Collections.reverse(temp);
}
b = !b;
res.add(temp);
}
return res;
}
}
19、NC81 二叉搜索树的第k个结点
TreeNode KthNode(TreeNode pRoot, int k)
import java.util.*;
// 中序遍历
public class Solution {
TreeNode KthNode(TreeNode pRoot, int k) {
if(pRoot==null) return null;
int count = 0;
List<TreeNode> stack = new ArrayList<>();
while(!stack.isEmpty() || pRoot!=null) {
if(pRoot!=null) {// 先往左找
stack.add(pRoot);
pRoot = pRoot.left;
}
else {//找到最左,出栈
pRoot = stack.remove(stack.size()-1);
count++;
if(count==k) return pRoot;
pRoot = pRoot.right;
}
}
return null;
}
}
public
class
Solution {
private
ArrayList<ArrayList<Integer>> lists =
new
ArrayList<>();
public
ArrayList<ArrayList<Integer>> pathSum (TreeNode root,
int
sum) {
ArrayList<Integer> list =
new
ArrayList<>();
recur(root, sum, list);
return
lists;
}
public
void
recur(TreeNode root,
int
sum, ArrayList<Integer> list) {
if
(root ==
null
)
return
;
list.add(root.val);
// 先加入list中
if
(root.left ==
null
&& root.right ==
null
) {
// 到达叶子结点
if
(sum == root.val) lists.add(
new
ArrayList<Integer>(list));
list.remove(list.size()-
1
);
// 移除当前结点
}
else
{
recur(root.left, sum - root.val, list);
recur(root.right, sum - root.val, list);
list.remove(list.size()-
1
);
// 递归返回时移除上一个结点
}
}
}
作者:哥们要飞