一、NC117 合并二叉树java
public TreeNode mergeTrees (TreeNode t1, TreeNode t2)node
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; // 此时 t一、t2 均不为 null // 合并节点的值 t1.val = t1.val + t2.val; // 合并左子树 t1.left = mergeTrees(t1.left, t2.left); // 合并右子树 t1.right = mergeTrees(t1.right, t2.right); return t1; } }
二、NC161 二叉树的中序遍历数组
public int[] inorderTraversal (TreeNode root)函数
解法1:递归ui
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:非递归(往左找,出栈往右找)spa
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(); }
三、NC72 二叉树的镜像3d
public TreeNode Mirror (TreeNode pRoot)code
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; }
四、NC13 二叉树的最大深度blog
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); } }
五、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; }
六、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; }
七、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; } }
八、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); }
九、判断二叉树是否对称
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; }
十、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
十一、NC9 二叉树中是否存在节点和为指定值的路径---dfs/回溯
public boolean hasPathSum (TreeNode root, int sum)
方法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); }
十二、NC5 二叉树根节点到叶子节点的全部路径和---dfs
public int sumNumbers (TreeNode root)
public class Solution { List<Integer> list; public int sumNumbers (TreeNode root) { // write code here list=new ArrayList(); sumNumbersHelp(root,0); int count=0; for(Integer l:list){ count+=l; } return count; } public void sumNumbersHelp (TreeNode root,int num) { if (root != null) { num=num*10+root.val; if (root.left == null && root.right == null) { // 当前节点是叶子节点 list.add(num); // 把路径加入到答案中 } else { // 当前节点不是叶子节点,继续递归遍历 sumNumbersHelp(root.left, num); sumNumbersHelp(root.right, num); } } } }