栈队列链表二叉树
栈和队列
1. 栈的实现
1 import java.util.EmptyStackException; 2 3 //基于数组实现的栈 4 public class ArrayStack { 5 private int[] arr; 6 private int top; 7 8 ArrayStack(int initialSize) { 9 if (initialSize <= 0) 10 throw new RuntimeException("非法初始化参数:" + initialSize); 11 top = -1; 12 arr = new int[initialSize]; 13 } 14 15 public void push(int x) { 16 if (top == arr.length - 1) 17 throw new StackOverflowError(); 18 arr[++top] = x; 19 } 20 21 public int pop() { 22 if (top < 0) 23 throw new EmptyStackException(); 24 return arr[top--]; 25 } 26 27 public int peek() { 28 if (top < 0) 29 throw new EmptyStackException(); 30 return arr[top]; 31 } 32 33 public boolean isEmpty() { 34 return top == -1; 35 } 36 }
1 import java.util.EmptyStackException; 2 import java.util.LinkedList; 3 4 //基于链表实现栈 5 public class ListStack { 6 private LinkedList<Integer> list = new LinkedList<>(); 7 8 public void push(int x) { 9 list.addLast(x); 10 } 11 12 public int pop() { 13 if (list.size() <= 0) 14 throw new EmptyStackException(); 15 return list.removeLast(); 16 } 17 18 public int peek() { 19 if (list.size() <= 0) 20 throw new EmptyStackException(); 21 return list.getLast(); 22 } 23 24 public boolean isEmpty() { 25 return list.size() == 0; 26 } 27 }
2. 队列实现
1 /** 2 * 顺序队列的假溢出 3 * 改进为循环队列 4 * head指向队列的第一个元素 5 * tail指向队尾的下一个位置 6 * 实际存储的元素数为len-1(区分队列空和队列满的情况) 7 */ 8 public class ArrayQueue { 9 private int[] arr; 10 private int head; 11 private int tail; 12 private int len; 13 14 ArrayQueue(int len) { 15 this.len = len; 16 arr = new int[len]; 17 } 18 19 public void offer(int x) { 20 if ((tail + 1) % len == head) 21 throw new RuntimeException("circle queue is Full"); 22 arr[tail] = x; 23 tail = (tail + 1) % len; 24 } 25 26 public int poll() { 27 if (head == tail) 28 throw new RuntimeException("circle queue is Null"); 29 int n = arr[head]; 30 head = (head + 1) % len; 31 return n; 32 } 33 }
1 import java.util.LinkedList; 2 import java.util.Queue; 3 4 public class ListQueue { 5 private Queue<Integer> queue = new LinkedList<>(); 6 7 public int peek() { 8 return queue.peek(); 9 } 10 11 public boolean offer(int x) { 12 return queue.offer(x); 13 } 14 15 public int poll() { 16 return queue.poll(); 17 } 18 19 public boolean isEmpty() { 20 return queue.isEmpty(); 21 } 22 }
3. 两个栈实现一个队列
1 import java.util.Stack; 2 3 public class MyQueue { 4 5 private Stack<Integer> in; 6 private Stack<Integer> out; 7 8 public MyQueue() { 9 in = new Stack<>(); 10 out = new Stack<>(); 11 } 12 13 public void push(int x) { 14 in.push(x); 15 } 16 17 public int pop() { 18 if (out.isEmpty()) 19 while (!in.isEmpty()) 20 out.push(in.pop()); 21 return out.pop(); 22 } 23 24 public int peek() { 25 if (out.isEmpty()) 26 while (!in.isEmpty()) 27 out.push(in.pop()); 28 return out.peek(); 29 } 30 31 public boolean empty() { 32 return in.isEmpty() && out.isEmpty(); 33 } 34 }
4. 两个队列实现一个栈
1 import java.util.Stack; 2 3 public class MinStack { 4 5 private Stack<Integer> stack; 6 private Stack<Integer> stackMin; 7 8 public MinStack() { 9 stack = new Stack<>(); 10 stackMin = new Stack<>(); 11 } 12 13 public void push(int x) { 14 stack.push(x); 15 if (stackMin.isEmpty()) { 16 stackMin.push(x); 17 } else { 18 stackMin.push(stackMin.peek() < x ? stackMin.peek() : x); 19 } 20 } 21 22 public void pop() { 23 stack.pop(); 24 stackMin.pop(); 25 } 26 27 public int top() { 28 return stack.peek(); 29 } 30 31 public int getMin() { 32 return stackMin.peek(); 33 } 34 }
5. 设计含最小函数min的栈
1 import java.util.Stack; 2 3 public class MinStack { 4 5 private Stack<Integer> stack; 6 private Stack<Integer> stackMin; 7 8 public MinStack() { 9 stack = new Stack<>(); 10 stackMin = new Stack<>(); 11 } 12 13 public void push(int x) { 14 stack.push(x); 15 if (stackMin.isEmpty()) { 16 stackMin.push(x); 17 } else { 18 stackMin.push(stackMin.peek() < x ? stackMin.peek() : x); 19 } 20 } 21 22 public void pop() { 23 stack.pop(); 24 stackMin.pop(); 25 } 26 27 public int top() { 28 return stack.peek(); 29 } 30 31 public int getMin() { 32 return stackMin.peek(); 33 } 34 }
6. 判断出栈序列是否合法
1 import java.util.Stack; 2 3 public class Main946 { 4 public boolean validateStackSequences(int[] pushed, int[] popped) { 5 Stack<Integer> stack = new Stack<>(); 6 int popIndex = 0; 7 for (int i = 0; i < pushed.length; i++) { 8 stack.push(pushed[i]); 9 while (!stack.empty() && stack.peek() == popped[popIndex]) { 10 stack.pop(); 11 popIndex++; 12 } 13 } 14 return stack.empty(); 15 } 16 }
链表
1 import java.util.HashSet; 2 import java.util.Stack; 3 4 public class List { 5 static class Node { 6 int val; 7 Node next; 8 9 public Node(int val) { 10 this.val = val; 11 } 12 } 13 14 //创建链表 15 private Node head; 16 private Node current; 17 18 public void add(int val) { 19 if (head == null) { 20 head = new Node(val); 21 current = head; 22 } else { 23 current.next = new Node(val); 24 current = current.next; 25 } 26 } 27 28 //遍历输出链表 29 public static void print(Node head) { 30 if (head == null) 31 return; 32 Node cur = head; 33 while (cur.next != null) { 34 System.out.print(cur.val + "->"); 35 cur = cur.next; 36 } 37 System.out.println(cur.val); 38 } 39 40 //获取链表节点数 41 private static int getLength(Node head) { 42 if (head == null) return 0; 43 int count = 0; 44 Node cur = head; 45 while (cur != null) { 46 count++; 47 cur = cur.next; 48 } 49 return count; 50 } 51 52 //查找倒数第k个节点 53 public static int findLastNode(Node head, int k) { 54 if (k == 0 || head == null) 55 return -1; 56 int size = getLength(head); 57 if (k > size) return -1; 58 Node cur = head; 59 for (int i = 0; i < size - k; i++) { 60 cur = cur.next; 61 } 62 return cur.val; 63 } 64 65 //在不允许遍历链表长度的情况下查找倒数第k个节点 66 public static int findLastNode2(Node head, int k) { 67 if (k == 0 || head == null) 68 return -1; 69 Node fast = head, slow = head; 70 for (int i = 0; i < k - 1; i++) { 71 fast = fast.next; 72 if (fast == null) 73 return -1; 74 } 75 while (fast.next != null) { 76 slow = slow.next; 77 fast = fast.next; 78 } 79 return slow.val; 80 } 81 82 //查找中间节点 83 public static int findMidNode(Node head) { 84 if (head == null) 85 return -1; 86 Node fast = head, slow = head; 87 while (fast != null && fast.next != null) { 88 slow = slow.next; 89 fast = fast.next.next; 90 } 91 return slow.val; 92 } 93 94 //合并两个有序链表 95 private static Node mergeTwoLists(Node l1, Node l2) { 96 if (l1 == null) 97 return l2; 98 if (l2 == null) 99 return l1; 100 if (l1.val < l2.val) { 101 l1.next = mergeTwoLists(l1.next, l2); 102 return l1; 103 } else { 104 l2.next = mergeTwoLists(l1, l2.next); 105 return l2; 106 } 107 } 108 109 //循环翻转 110 public static Node reverseListByLoop(Node head) { 111 Node pre = null; 112 Node next = null; 113 while (head != null) { 114 next = head.next; 115 head.next = pre; 116 pre = head; 117 head = next; 118 } 119 return pre; 120 } 121 122 //递归翻转 123 public static Node reverseListByRecursion(Node head) { 124 if (head == null || head.next == null) 125 return head; 126 Node pre = reverseListByRecursion(head.next); 127 head.next.next = head; 128 head.next = null; 129 return pre; 130 } 131 132 //反向打印链表 133 public static void reversePrint(Node head) { 134 if (head == null) 135 return; 136 Stack<Node> stack = new Stack<>(); 137 Node cur = head; 138 while (cur != null) { 139 stack.push(cur); 140 cur = cur.next; 141 } 142 while (!stack.isEmpty()) { 143 System.out.print(stack.pop().val + " "); 144 } 145 System.out.println(); 146 } 147 148 //判断单链表是否有环 149 public static Node hasCycle(Node head) { 150 if (head == null) 151 return null; 152 Node fast = head, slow = head; 153 while (fast != null && fast.next != null) { 154 slow = slow.next; 155 fast = fast.next.next; 156 if (slow == fast) 157 return slow; 158 } 159 return null; 160 } 161 162 //创建有环链表 163 public void add(Node node) { 164 if (node == null) 165 return; 166 if (head == null) { 167 head = node; 168 current = head; 169 } else { 170 current.next = node; 171 current = current.next; 172 } 173 } 174 175 //获取有环链表环的长度 176 public static int getCycleLength(Node node) { 177 Node cur = node; 178 int length = 0; 179 while (cur != null) { 180 cur = cur.next; 181 length++; 182 if (cur == node) 183 return length; 184 } 185 return length; 186 } 187 188 //获取环的起点 189 public static Node getCycleStart(Node head) { 190 if (head == null) 191 return null; 192 Node fast = head, slow = head; 193 while (fast != null && fast.next != null) { 194 slow = slow.next; 195 fast = fast.next.next; 196 if (slow == fast) { 197 fast = head; 198 /* 199 假设链表起点到环的起点为x 200 链表起点到快慢指针相遇节点为x+z 201 环的长度为y 202 那么有2(x+z)-(x+z)=k*y 203 即x=k*y-z=y-z+(k-1)*y 204 */ 205 while (slow != fast) { 206 slow = slow.next; 207 fast = fast.next; 208 } 209 return slow; 210 } 211 } 212 return null; 213 } 214 215 //获取环的起点2 216 public static Node getCycleStart2(Node head) { 217 HashSet<Node> set = new HashSet<>(); 218 while (head != null) { 219 if (!set.add(head)) 220 return head; 221 head = head.next; 222 } 223 return null; 224 } 225 226 /* 227 获取两个单链表相交的第一个节点 228 1.压入栈中,依次比较找出最后一个相同的节点,时间空间复杂度均为O(len1+len2) 229 2.快慢指针 230 */ 231 public static Node getFirstCommonNode(Node l1, Node l2) { 232 if (l1 == null || l2 == null) 233 return null; 234 int len1 = getLength(l1); 235 int len2 = getLength(l2); 236 Node longHead = len1 > len2 ? l1 : l2, shortHead = len1 > len2 ? l2 : l1; 237 238 for (int i = 0; i < Math.abs(len1 - len2); i++) longHead = longHead.next; 239 while (longHead != null && shortHead != null) { 240 if (longHead == shortHead) 241 return longHead; 242 longHead = longHead.next; 243 shortHead = shortHead.next; 244 } 245 return null; 246 } 247 }
二叉树
1 import java.util.*; 2 3 class TreeNode{ 4 int val; 5 TreeNode left; 6 TreeNode right; 7 8 public TreeNode(int val){ 9 this.val=val; 10 } 11 } 12 13 public class Tree { 14 //递归求二叉树节点个数 15 public static int getNodeNumByRecursion(TreeNode root){ 16 if(root==null) 17 return 0; 18 return getNodeNumByRecursion(root.left)+getNodeNumByRecursion(root.right)+1; 19 } 20 //迭代求二叉树节点个数 21 public static int getNodeNumByLoop(TreeNode root){ 22 if(root==null) 23 return 0; 24 int count=1; 25 Queue<TreeNode> queue=new LinkedList<>(); 26 queue.add(root); 27 28 while(!queue.isEmpty()){ 29 TreeNode cur=queue.remove(); 30 if(cur.left!=null){ 31 queue.add(cur.left); 32 count++; 33 } 34 if(cur.right!=null){ 35 queue.add(cur.right); 36 count++; 37 } 38 } 39 return count; 40 } 41 42 //递归求二叉树的深度 43 public static int getDepthByRecursion(TreeNode root){ 44 if(root==null) 45 return 0; 46 return Math.max(getDepthByRecursion(root.left),getDepthByRecursion(root.right))+1; 47 } 48 //迭代求二叉树的深度 49 public static int getDepthByLoop(TreeNode root){ 50 if(root==null) 51 return 0; 52 int depth=0; 53 int currentLevelNodes=1; 54 int nextLevelNodes=0; 55 Queue<TreeNode> queue=new LinkedList<>(); 56 queue.add(root); 57 58 while(!queue.isEmpty()){ 59 TreeNode cur=queue.remove(); 60 currentLevelNodes--; 61 if(cur.left!=null){ 62 queue.add(cur.left); 63 nextLevelNodes++; 64 } 65 if(cur.right!=null){ 66 queue.add(cur.right); 67 nextLevelNodes++; 68 } 69 if(currentLevelNodes==0){ 70 depth++; 71 currentLevelNodes=nextLevelNodes; 72 nextLevelNodes=0; 73 } 74 } 75 return depth; 76 } 77 78 //递归前序遍历 79 public static void preorderTraversalByRecursion(TreeNode root){ 80 if(root==null) 81 return; 82 System.out.print(root.val+" "); 83 preorderTraversalByRecursion(root.left); 84 preorderTraversalByRecursion(root.right); 85 } 86 //迭代前序遍历 87 public static void preorderTraversalByLoop(TreeNode root){ 88 if(root==null) 89 return; 90 Stack<TreeNode> stack=new Stack<>(); 91 stack.push(root); 92 93 while(!stack.isEmpty()){ 94 TreeNode cur=stack.pop(); 95 System.out.print(cur.val+" "); 96 if(cur.right!=null) 97 stack.push(cur.right); 98 if(cur.left!=null) 99 stack.push(cur.left); 100 } 101 } 102 103 //递归中序遍历 104 public static void inorderTraversalByRecursion(TreeNode root){ 105 if(root==null) 106 return; 107 inorderTraversalByRecursion(root.left); 108 System.out.print(root.val+" "); 109 inorderTraversalByRecursion(root.right); 110 } 111 //迭代中序遍历 112 //todo 113 public static void inorderTraversalByLoop(TreeNode root){ 114 if(root==null) 115 return; 116 Stack<TreeNode> stack=new Stack<>(); 117 TreeNode cur=root; 118 119 while(true){ 120 while(cur!=null){ 121 stack.push(cur); 122 cur=cur.left; 123 } 124 if(stack.isEmpty()) 125 break; 126 cur=stack.pop(); 127 System.out.print(cur.val+" "); 128 cur=cur.right; 129 } 130 } 131 132 //递归后序遍历 133 public static void postorderTraversalByRecursion(TreeNode root){ 134 if(root==null) 135 return; 136 postorderTraversalByRecursion(root.left); 137 postorderTraversalByRecursion(root.right); 138 System.out.print(root.val+" "); 139 } 140 //迭代后序遍历 141 //todo 142 public static void postorderTraversalByLoop(TreeNode root){ 143 if(root==null) 144 return; 145 Stack<TreeNode> stack=new Stack<>(); 146 Stack<TreeNode> output=new Stack<>(); 147 stack.push(root); 148 149 while(!stack.isEmpty()){ 150 TreeNode cur=stack.pop(); 151 output.push(cur); 152 if(cur.left!=null) 153 stack.push(cur.left); 154 if(cur.right!=null) 155 stack.push(cur.right); 156 } 157 while(!output.isEmpty()) System.out.print(output.pop().val+" "); 158 } 159 160 //递归分层遍历二叉树 161 //todo 162 public static void levelTraversalByRecursion(TreeNode root){ 163 ArrayList<ArrayList<Integer>> res=new ArrayList<>(); 164 dfs(root,0,res); 165 System.out.print(res); 166 167 } 168 private static void dfs(TreeNode root,int level,ArrayList<ArrayList<Integer>> res){ 169 if(root==null) 170 return; 171 if(level>=res.size()) 172 res.add(new ArrayList<>()); 173 res.get(level).add(root.val); 174 dfs(root.left,level+1,res); 175 dfs(root.right,level+1,res); 176 } 177 //迭代分层遍历二叉树 178 public static void levelTraversalByLoop(TreeNode root){ 179 if (root == null) 180 return; 181 LinkedList<TreeNode> queue = new LinkedList<>(); 182 queue.push(root); 183 184 while (!queue.isEmpty()) { 185 TreeNode cur = queue.removeFirst(); 186 System.out.print(cur.val + " "); 187 if (cur.left != null) queue.add(cur.left); 188 if (cur.right != null) queue.add(cur.right); 189 } 190 } 191 192 //递归 二叉查找树转为有序的双向链表 仅仅调节指针 193 //todo 需要仔细琢磨 194 public static TreeNode convertBST2DLLByRecursion(TreeNode root){ 195 root=convertBST2DLL(root); 196 while(root.left!=null) 197 root=root.left; 198 return root; 199 } 200 private static TreeNode convertBST2DLL(TreeNode root){ 201 if(root==null||(root.left==null&&root.right==null)) 202 return root; 203 TreeNode cur=null; 204 if(root.left!=null){ 205 cur=convertBST2DLL(root.left); 206 while(cur.right!=null) 207 cur=cur.right; 208 cur.right=root; 209 root.left=cur; 210 } 211 if(root.right!=null){ 212 cur=convertBST2DLL(root.right); 213 while(cur.left!=null) 214 cur=cur.left; 215 cur.left=root; 216 root.right=cur; 217 } 218 return root; 219 } 220 //迭代 二叉查找树转为有序的双向链表 仅仅调节指针 221 //todo 222 public static TreeNode convertBST2DLLByLoop(TreeNode root){ 223 if(root==null) 224 return null; 225 TreeNode head=null,cur=root,pre=null; 226 Stack<TreeNode> stack=new Stack<>(); 227 228 while(!stack.isEmpty()||cur!=null){ 229 while(cur!=null){ 230 stack.push(cur); 231 cur=cur.left; 232 } 233 if(!stack.isEmpty()){ 234 cur=stack.pop(); 235 if(head==null) 236 head=cur; 237 if(pre!=null){ 238 pre.right=cur; 239 cur.left=pre; 240 } 241 pre=cur; 242 cur=cur.right; 243 } 244 } 245 return head; 246 } 247 248 //递归求二叉树的第k层的节点个数 249 public static int getNodeNumKthLevelByRecursion(TreeNode root,int k){ 250 if(root==null||k<1) 251 return 0; 252 if(k==1) 253 return 1; 254 return getNodeNumKthLevelByRecursion(root.left,k-1)+getNodeNumKthLevelByRecursion(root.right,k-1); 255 } 256 //迭代求二叉树的第k层的节点个数 257 public static int getNodeNumKthLevelByLoop(TreeNode root,int k){ 258 if(root==null) 259 return 0; 260 Queue<TreeNode> queue=new LinkedList<>(); 261 queue.add(root); 262 263 int i=1; 264 int currentLevelNodes=1; 265 int nextLevelNodes=0; 266 267 while(!queue.isEmpty()&&i<k){ 268 TreeNode cur=queue.remove(); 269 currentLevelNodes--; 270 if(cur.left!=null){ 271 queue.add(cur.left); 272 nextLevelNodes++; 273 } 274 if(cur.right!=null){ 275 queue.add(cur.right); 276 nextLevelNodes++; 277 } 278 if(currentLevelNodes==0){ 279 currentLevelNodes=nextLevelNodes; 280 nextLevelNodes=0; 281 i++; 282 } 283 } 284 return currentLevelNodes; 285 } 286 287 //递归求二叉树的叶子节点个数 288 public static int getNodeNumLeafByRecursion(TreeNode root){ 289 if(root==null) 290 return 0; 291 if(root.left==null&&root.right==null) 292 return 1; 293 return getNodeNumLeafByRecursion(root.left)+getNodeNumLeafByRecursion(root.right); 294 } 295 //迭代求二叉树的叶子节点个数 基于Level order traversal 296 public static int getNodeNumLeafByLoop(TreeNode root){ 297 if(root==null) 298 return 0; 299 Queue<TreeNode> queue=new LinkedList<>(); 300 queue.add(root); 301 302 int leafNodes=0; 303 while(!queue.isEmpty()){ 304 TreeNode cur=queue.remove(); 305 if(cur.left!=null) 306 queue.add(cur.left); 307 if(cur.right!=null) 308 queue.add(cur.right); 309 if(cur.left==null&&cur.right==null) 310 leafNodes++; 311 } 312 return leafNodes; 313 } 314 315 //递归判断两个二叉树是否一样 316 public static boolean isSameTreeByRecursion(TreeNode r1,TreeNode r2){ 317 if(r1==null&&r2==null) 318 return true; 319 if(r1==null||r2==null) 320 return false; 321 if(r1.val!=r2.val) 322 return false; 323 return isSameTreeByRecursion(r1.left,r2.left)&&isSameTreeByRecursion(r1.right,r2.right); 324 } 325 //迭代判断两个二叉树是否一样 326 public static boolean isSameTreeByLoop(TreeNode r1,TreeNode r2){ 327 if(r1==null&&r2==null) 328 return true; 329 if(r1==null||r2==null) 330 return false; 331 Stack<TreeNode> stack1=new Stack<>(); 332 Stack<TreeNode> stack2=new Stack<>(); 333 stack1.push(r1); 334 stack2.push(r2); 335 336 while(!stack1.isEmpty()&&!stack2.isEmpty()){ 337 TreeNode n1=stack1.pop(); 338 TreeNode n2=stack2.pop(); 339 if(n1==null&&n2==null) 340 continue; 341 else if(n1!=null&&n2!=null&&n1.val==n2.val){ 342 stack1.push(n1.right); 343 stack1.push(n1.left); 344 stack2.push(n2.right); 345 stack2.push(n2.left); 346 } 347 else 348 return false; 349 } 350 return true; 351 } 352 353 //递归判断二叉树是否为平衡二叉树 354 public static boolean isAVLByRecursion(TreeNode root){ 355 if(root==null) 356 return true; 357 if(Math.abs(getDepthByRecursion(root.left)-getDepthByRecursion(root.right))>1) 358 return false; 359 return isAVLByRecursion(root.left)&&isAVLByRecursion(root.right); 360 } 361 362 //递归求二叉树的镜像,破坏原有的树 363 public static TreeNode mirrorByRecursion(TreeNode root){ 364 if(root==null) 365 return null; 366 TreeNode left=mirrorByRecursion(root.left); 367 TreeNode right=mirrorByRecursion(root.right); 368 root.left=right; 369 root.right=left; 370 return root; 371 } 372 //迭代求二叉树的镜像,破坏原有的树 373 public static void mirrorByLoop(TreeNode root){ 374 if(root==null) 375 return; 376 Stack<TreeNode> stack=new Stack<>(); 377 stack.push(root); 378 379 while(!stack.isEmpty()){ 380 TreeNode cur=stack.pop(); 381 TreeNode tmp=cur.right; 382 cur.right=cur.left; 383 cur.left=tmp; 384 385 if(cur.left!=null) 386 stack.push(cur.left); 387 if(cur.right!=null) 388 stack.push(cur.right); 389 } 390 } 391 392 //递归求二叉树的镜像,不破坏原有的树 393 public static TreeNode mirrorCopyByRecursion(TreeNode root){ 394 if(root==null) 395 return null; 396 TreeNode newNode=new TreeNode(root.val); 397 newNode.left=mirrorCopyByRecursion(root.right); 398 newNode.right=mirrorCopyByRecursion(root.left); 399 return newNode; 400 } 401 //迭代求二叉树的镜像,不破坏原有的树 402 public static TreeNode mirrorCopyByLoop(TreeNode root){ 403 if(root==null) 404 return null; 405 Stack<TreeNode> stack=new Stack<>(); 406 Stack<TreeNode> newStack=new Stack<>(); 407 stack.push(root); 408 TreeNode newRoot=new TreeNode(root.val); 409 newStack.push(newRoot); 410 411 while(!stack.isEmpty()){ 412 TreeNode cur=stack.pop(); 413 TreeNode newCur=newStack.pop(); 414 415 if(cur.right!=null){ 416 stack.push(cur.right); 417 newCur.left=new TreeNode(cur.right.val); 418 newStack.push(newCur.left); 419 } 420 if(cur.left!=null){ 421 stack.push(cur.left); 422 newCur.right = new TreeNode(cur.left.val); 423 newStack.push(newCur.right); 424 } 425 } 426 return newRoot; 427 } 428 429 //递归判断两棵树是否相互镜像 430 public static boolean isMirrorByRecursion(TreeNode r1,TreeNode r2){ 431 if(r1==null&&r2==null) 432 return true; 433 if(r1==null||r2==null) 434 return false; 435 if(r1.val!=r2.val) 436 return false; 437 return isMirrorByRecursion(r1.left,r2.right)&&isMirrorByRecursion(r1.right,r2.left); 438 } 439 440 //递归求最低公共父节点 441 public static TreeNode getLastCommonParentByRecursion(TreeNode root,TreeNode n1,TreeNode n2){ 442 if(root==null||root==n1||root==n2) 443 return root; 444 TreeNode left=getLastCommonParentByRecursion(root.left,n1,n2); 445 TreeNode right=getLastCommonParentByRecursion(root.right,n1,n2); 446 return left==null?right:right==null?left:root; 447 } 448 //迭代求最低公共父节点 449 //todo 450 public static TreeNode getLastCommonParentByLoop(TreeNode root,TreeNode n1,TreeNode n2){ 451 Map<TreeNode,TreeNode> parent = new HashMap<>(); 452 Deque<TreeNode> stack = new ArrayDeque<>(); 453 parent.put(root,null); 454 stack.push(root); 455 456 while(!parent.containsKey(n1)||!parent.containsKey(n2)){ 457 TreeNode node = stack.pop(); 458 if(node.left!=null){ 459 parent.put(node.left,node); 460 stack.push(node.left); 461 } 462 if(node.right!=null){ 463 parent.put(node.right,node); 464 stack.push(node.right); 465 } 466 } 467 Set<TreeNode> ancestors = new HashSet<>(); 468 while(n1!=null){ 469 ancestors.add(n1); 470 n1=parent.get(n1); 471 } 472 while(!ancestors.contains(n2)) 473 n2=parent.get(n2); 474 return n2; 475 } 476 477 //递归求二叉树节点最大距离 478 public static int getMaxDistanceByRecursion(TreeNode root){ 479 if(root==null) 480 return 0; 481 int k=depth(root.left)+depth(root.right); 482 int left=getMaxDistanceByRecursion(root.left); 483 int right=getMaxDistanceByRecursion(root.right); 484 return Math.max(k,Math.max(left,right)); 485 } 486 private static int depth(TreeNode root){ 487 if(root==null) 488 return 0; 489 return Math.max(depth(root.left),depth(root.right))+1; 490 } 491 492 //递归 由前序遍历序列和中序遍历序列重建二叉树 493 //todo 494 public static TreeNode rebuildBinaryTreeByRecursion(int[] preorder,int[] inorder){ 495 return buildTree(preorder,0,inorder,inorder.length-1,0); 496 } 497 private static TreeNode buildTree(int[] preorder,int idx,int[] inorder,int end,int start){ 498 if(idx>=preorder.length||start>end) 499 return null; 500 TreeNode root = new TreeNode(preorder[idx]); 501 int i; 502 for(i=end;i>=start;i--){ 503 if(preorder[idx]==inorder[i]) 504 break; 505 } 506 root.left=buildTree(preorder,idx+1,inorder,i-1,start); 507 root.right=buildTree(preorder,idx+i-start+1,inorder,end,i+1); 508 return root; 509 } 510 511 //迭代判断二叉树是不是完全二叉树 512 public static boolean isCompleteBinaryTreeByLoop(TreeNode root){ 513 if(root==null) 514 return false; 515 516 Queue<TreeNode> queue=new LinkedList<>(); 517 queue.add(root); 518 boolean mustHaveNoChild=false; 519 boolean result=true; 520 521 while(!queue.isEmpty()){ 522 TreeNode cur=queue.remove(); 523 if(mustHaveNoChild){ 524 if(cur.left!=null||cur.right!=null){ 525 result=false; 526 break; 527 } 528 }else { 529 if(cur.left!=null&&cur.right!=null){ 530 queue.add(cur.left); 531 queue.add(cur.right); 532 }else if(cur.left!=null&&cur.right==null){ 533 mustHaveNoChild=true; 534 queue.add(cur.left); 535 }else if(cur.left==null&&cur.right!=null){ 536 result=false; 537 break; 538 }else{ 539 mustHaveNoChild=true; 540 } 541 } 542 } 543 return result; 544 } 545 546 }