【算法题-分类型总结】二叉树相关的算法题
1、判断平衡二叉树
思路:辅助函数输出子树长度&全局变量在两个函数内修改
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; } } |
2、中序遍历
思路:递归/栈实现左中右(入栈出栈)
/** * 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 List<Integer> inorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<>(); inOrder(root, list); return list; }
public void inOrder(TreeNode root, List<Integer> list) { if(root == null) { return; } inOrder(root.left, list); list.add(root.val); inOrder(root.right, list); } } //非递归方式 class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<>(); Stack<TreeNode> stack = new Stack<>(); //Deque<TreeNode> stack = new LinkedList<TreeNode>(); //栈非空是isEmpty()而不是!=null while(root != null || !stack.isEmpty()) { while(root != null) { stack.push(root); root = root.left; } root = stack.pop(); list.add(root.val); root = root.right; } return list; } } |
3、层序遍历
思路:队列+定义每层元素中的size
import java.util.*;
/* * public class TreeNode { * int val = 0; * TreeNode left = null; * TreeNode right = null; * } */
public class Solution { ArrayList<ArrayList<Integer>> res = new ArrayList<>(); /** * * @param root TreeNode类 * @return int整型ArrayList<ArrayList<>> */ public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) { level(root); return res; }
public void level(TreeNode root) { Queue<TreeNode> queue = new LinkedList<>(); List<Integer> list = new ArrayList<>(); if(root == null) { return; } queue.add(root); while(!queue.isEmpty()) { //需要定义每一层元素的个数(队内元素个数) int size = queue.size(); while(size > 0) { TreeNode node = queue.poll(); list.add(node.val); if(node.left != null) { queue.add(node.left); } if(node.right != null) { queue.add(node.right); } size--; } res.add(new ArrayList<>(list)); list = new ArrayList<>(); } } } |
4、最近公共祖先
思路:递归实现+返回条件判断
/** * 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 || 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 null; } else if(left != null && right != null) { //均为非空时,说明左右均找到了p或q,则返回根节点 return root; } else { //否则,有一边没找到,则返回另一边 return left == null ? right : left; } } } |
5、直径/节点路径长度
思路:回溯-结束条件、记录路径、做选择
/** * 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 { int max = 0; public int diameterOfBinaryTree(TreeNode root) { dfs(root); return max; } public int dfs(TreeNode root) { if(root.left == null && root.right == null) { return 0; } int leftSize = root.left == null ? 0 : dfs(root.left) + 1; int rightSize = root.right == null ? 0 :dfs(root.right) + 1; max = Math.max(max, leftSize + rightSize); return Math.max(leftSize, rightSize); } } |
6、最大路径和
思路:根节点为空为出口&递归左右子树&max判断
/** * 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 { int res = Integer.MIN_VALUE; public int maxPathSum(TreeNode root) { maxPath(root); return res; } public int maxPath(TreeNode root) { if(root == null) { return 0; } int left = Math.max(maxPath(root.left), 0); int right = Math.max(maxPath(root.right), 0); res = Math.max(res, root.val + left + right); return root.val + Math.max(left, right); } } |
7、最大深度
思路:BFS层次遍历,使用队列记录size,每层+1/递归记录左右最大+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; * } * } */ //方法1:递归 class Solution { public int maxDepth(TreeNode root) { return root == null ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; } } //方法2:BFS,即层序遍历 //注意:队列和栈的使用,BFS用队列! class Solution { public int maxDepth(TreeNode root) { if(root == null) { return 0; } int level = 0; //队列要初始化成LinkedList Queue<TreeNode> queue = new LinkedList<>(); //队列添加元素用add或offer,栈用push queue.offer(root); while(!queue.isEmpty()) { int size = queue.size(); level++; for(int i = 0; i < size; i++) { //队列移除元素用remove/poll,栈用pop或top TreeNode node = queue.poll(); if(node.left != null) { queue.offer(node.left); } if(node.right != null) { queue.offer(node.right); } } } return level; } } //方法3:DFS,相当于用栈 class Solution { private int maxLen = 0; public int maxDepth(TreeNode root) { if(root == null) { return 0; } dfs(root, 1); return maxLen;
} public void dfs(TreeNode root, int level) { if(root == null) { return; } if(level > maxLen) { maxLen = level; } dfs(root.left, level + 1); dfs(root.right, level + 1); } } |
8、前序和中序构造二叉树
思路:辅助函数递归确定左右子树
import java.util.*; /** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public TreeNode reConstructBinaryTree(int [] pre,int [] vin) { return reConstructBinaryTree(pre, 0 , pre.length - 1, vin, 0, vin.length - 1); } public TreeNode reConstructBinaryTree(int [] pre, int preStart, int preEnd, int [] vin, int vinStart, int vinEnd) { //注意:临界点是前后位置,pre和end永远不为空 if(preStart > preEnd || vinStart > vinEnd) { return null; } TreeNode root = new TreeNode(pre[preStart]); for(int i = vinStart; i <= vinEnd; i++) { if(vin[i] == pre[preStart]) { //注意:先序的起始和结尾index,需要用vinStart和i表示 root.left = reConstructBinaryTree(pre, preStart + 1, preStart + i - vinStart, vin, vinStart, i - 1); root.right = reConstructBinaryTree(pre, preStart + i - vinStart + 1, preEnd, vin, i + 1, vinEnd); //注意确定了node的左右子节点后,无需后续的遍历过程,直接break结束本次循环 break; } } return root; } } |
9、锯齿/之字层次遍历
思路:层次遍历+记录序列奇偶
/** * 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 List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> res = new ArrayList<>(); circle(root, res, 0); return res; }
public void circle(TreeNode root, List<List<Integer>> res, int level) { if(root == null) { return; } if(res.size() == level) { res.add(new ArrayList<>()); } if((level & 1) == 1) { //相当于level/2,奇数层 res.get(level).add(0, root.val); //奇数层插入到前面 } else { res.get(level).add(root.val); } circle(root.left, res, level + 1); circle(root.right, res, level + 1); } } |
10、先序、中序、后序遍历
思路:递归+判空出口
方法1:递归
import java.util.*; public class Solution { /** * * @param root TreeNode类 the root of binary tree * @return int整型二维数组 */
public int[][] threeOrders (TreeNode root) { List<Integer> preList = new ArrayList<>(); List<Integer> inList = new ArrayList<>(); List<Integer> postList = new ArrayList<>(); preOrder(root, preList); inOrder(root, inList); postOrder(root, postList); int[][] res = new int[3][preList.size()]; //转为int数组,需要用mapToInt res[0] = preList.stream().mapToInt(Integer::valueOf).toArray(); res[1] = inList.stream().mapToInt(Integer::valueOf).toArray(); res[2] = postList.stream().mapToInt(Integer::valueOf).toArray(); return res; }
public void preOrder(TreeNode root, List<Integer> preList) { if(root == null) return; preList.add(root.val); preOrder(root.left, preList); preOrder(root.right, preList); }
public void inOrder(TreeNode root, List<Integer> inList) { if(root == null) return; inOrder(root.left, inList); inList.add(root.val); inOrder(root.right, inList); }
public void postOrder(TreeNode root, List<Integer> postList) { if(root == null) return; postOrder(root.left, postList); postOrder(root.right, postList); postList.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); } |
11、右视图
思路: 用队列找到每层的最后一个节点
(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; * } * } */ //BFS:层序遍历保留每一层的最后一个节点 class Solution { public List<Integer> rightSideView(TreeNode root) { List<Integer> res = new ArrayList<>(); if(root == null) { return res; } Queue<TreeNode> queue = new LinkedList<>(); //入队用offer queue.offer(root); while(!queue.isEmpty()) { int 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); } if(i == size - 1) { res.add(node.val); } } } return res; } }
//DFS:深度搜索,每一次的第一个加入 class Solution { public List<Integer> res = new ArrayList<>(); public List<Integer> rightSideView(TreeNode root) { dfs(root, 0); return res; } public void dfs(TreeNode root, int depth) { if(root == null) { return; } if(depth == res.size()) { res.add(root.val); } depth++; dfs(root.right, depth); dfs(root.left, depth); } } |
(2)给出前序和中序遍历,恢复二叉树并打印
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; } |
12、前序遍历非递归
思路:用栈和res实现
/** * 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 { List<Integer> res = new ArrayList<>(); public List<Integer> preorderTraversal(TreeNode root) { preOrder(root); return res; }
public void preOrder(TreeNode root) { if(root == null) { return; } Stack<TreeNode> stack = new Stack<>(); //表示栈非空需要使用函数 while(!stack.isEmpty() || root != null) { while(root != null) { //栈内元素可能为空,只剩一个root,右子树 res.add(root.val); stack.push(root); root = root.left; } root = stack.pop().right; } } } |
13、根到叶节点数字之和
思路:根计算&递归计算左右子树
//递归求和 /** * 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 { private int sum; public int sumNumbers(TreeNode root) { sum = 0; //初始传递0 sumNode(root, 0); return sum; } public void sumNode(TreeNode root, int val) { if(root == null) { return; } val = val * 10 + root.val; //加的条件是当前节点为最后一个节点 if(root.left == null && root.right == null) { sum += val; } sumNode(root.left, val); sumNode(root.right, val); } } |
14、根到叶等于目标值的路径
思路:DFS深度优先搜索
/** * 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 { private List<List<Integer>> res; public List<List<Integer>> pathSum(TreeNode root, int targetSum) { res = new ArrayList<>(); List<Integer> ans = new ArrayList<>(); dfs(root, ans, targetSum, 0); return res; } public void dfs(TreeNode node, List<Integer> ans, int targetSum, int num) { if(node == null) { return; } if(node.left == null && node.right == null && node.val + num == targetSum) { ans.add(node.val); res.add(new ArrayList(ans)); ans.remove(ans.size() - 1); return; } ans.add(node.val); dfs(node.left, ans, targetSum, num + node.val); dfs(node.right, ans, targetSum, num + node.val); //每个节点最后都要移除 ans.remove(ans.size() - 1); } } |
15、合并二叉树(节点值相加)
思路:递归
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; } } |
16、二叉树的镜像
思路:递归后交换返回的节点
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; } |
17、判断是否对称(为镜像)
思路:递归辅助函数判断左右是否为空及其值/使用Deque双端队列进行层次遍历
方法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; } |
18、是否存在指定和的路径
思路:递归&sum-根的值
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); } } |
19、根到叶节点的所有路径和
思路:数字拼接改变节点的值&使用栈存节点/递归
方法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); } } } } |
20、升序数组转平衡二叉树
思路:类似二分,选择中间元素作为根
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; } } |
21、判断是否为搜索二叉树
思路:回溯
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); } } |
22、二叉排序树第k个/小节点
思路:中序遍历第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; }
} |
23、重建并输出右视图
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * 求二叉树的右视图 * @param xianxu int整型一维数组 先序遍历 * @param zhongxu int整型一维数组 中序遍历 * @return int整型一维数组 */ //思路:使用队列BFS层次遍历,当到达最后一个节点时加入res public int[] solve (int[] xianxu, int[] zhongxu) { List<Integer> res = new ArrayList<>(); //先确定二叉树 TreeNode root = reconstrution(xianxu, 0, xianxu.length - 1, zhongxu, 0, zhongxu.length - 1); //使用队列,对树进行层次遍历 Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while(!queue.isEmpty()) { int size = queue.size(); for(int i = 0; i < size; i++) { if(i == size - 1) { res.add(queue.peek().val); } TreeNode node = queue.poll(); if(node.left != null) { queue.offer(node.left); } if(node.right != null) { queue.offer(node.right); } } } return res.stream().mapToInt(x -> x).toArray(); } //递归,类似回溯:路径、选择列表、结束条件 //但是回溯要移除选择,而递归无需移除选择 public TreeNode reconstrution(int[] xianxu, int preStart, int preEnd, int[] zhongxu, int inStart, int inEnd) { if(preStart > preEnd || inStart > inEnd) { return null; } TreeNode root = new TreeNode(xianxu[preStart]); //找到中序的位置 int i = 0; for(i = inStart; i <= inEnd; i++) { if(zhongxu[i] == xianxu[preStart]) { break; } } root.left = reconstrution(xianxu, preStart + 1, preStart + (i - inStart), zhongxu, inStart, i - 1); root.right = reconstrution(xianxu, preStart + (i - inStart) + 1, preEnd, zhongxu, i + 1, inEnd); return root; } }
本文来自博客园,作者:哥们要飞,转载请注明原文链接:https://www.cnblogs.com/liujinhui/p/15891701.html