一、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); } } } }