【算法题型总结】--4、树
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
);
// 递归返回时移除上一个结点
}
}
}
本文来自博客园,作者:哥们要飞,转载请注明原文链接:https://www.cnblogs.com/liujinhui/p/15134973.html