From 39fc3ed9a8ddc1aa4139831617efb7e4f4750e68 Mon Sep 17 00:00:00 2001 From: markilue <745518019@qq.com> Date: Thu, 22 Sep 2022 13:19:38 +0800 Subject: [PATCH] =?UTF-8?q?leecode=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/markilue/leecode/tree/MaxDepth.java | 214 ++++++++++++++++++ .../com/markilue/leecode/tree/MinDepth.java | 179 +++++++++++++++ 2 files changed, 393 insertions(+) create mode 100644 Leecode/src/main/java/com/markilue/leecode/tree/MaxDepth.java create mode 100644 Leecode/src/main/java/com/markilue/leecode/tree/MinDepth.java diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/MaxDepth.java b/Leecode/src/main/java/com/markilue/leecode/tree/MaxDepth.java new file mode 100644 index 0000000..7edad50 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/MaxDepth.java @@ -0,0 +1,214 @@ +package com.markilue.leecode.tree; + +import org.junit.Test; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * @BelongsProject: Leecode + * @BelongsPackage: com.markilue.leecode.tree + * @Author: dingjiawen + * @CreateTime: 2022-09-22 10:23 + * @Description: TODO 力扣104题:二叉树的最大深度: + * 给定一个二叉树,找出其最大深度。 + * 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 + * 说明: 叶子节点是指没有子节点的节点。 + * @Version: 1.0 + */ +public class MaxDepth { + + @Test + public void test() { + + TreeNode root = new TreeNode(3); + TreeNode TreeNode2 = new TreeNode(9); + TreeNode TreeNode3 = new TreeNode(20); +// TreeNode TreeNode4 = new TreeNode(4); +// TreeNode TreeNode5 = new TreeNode(5); + TreeNode TreeNode6 = new TreeNode(15); + TreeNode TreeNode7 = new TreeNode(7); + + root.setRight(TreeNode3); + root.setLeft(TreeNode2); +// TreeNode2.setLeft(TreeNode4); +// TreeNode2.setRight(TreeNode5); + TreeNode3.setRight(TreeNode7); + TreeNode3.setLeft(TreeNode6); + + System.out.println(maxDepth(root)); + + } + + @Test + public void test1() { + + TreeNode root = new TreeNode(3); + TreeNode TreeNode2 = new TreeNode(9); + TreeNode TreeNode3 = new TreeNode(20); +// TreeNode TreeNode4 = new TreeNode(4); +// TreeNode TreeNode5 = new TreeNode(5); + TreeNode TreeNode6 = new TreeNode(15); + TreeNode TreeNode7 = new TreeNode(7); + +// root.setRight(TreeNode3); +// root.setLeft(TreeNode2); +// TreeNode2.setLeft(TreeNode4); +// TreeNode2.setRight(TreeNode5); +// TreeNode3.setRight(TreeNode7); +// TreeNode3.setLeft(TreeNode6); + + System.out.println(maxDepth(root)); + + } + + + @Test + public void test2(){ + TreeNode root = new TreeNode(4); + TreeNode TreeNode2 = new TreeNode(2); + TreeNode TreeNode3 = new TreeNode(6); + TreeNode TreeNode4 = new TreeNode(1); + TreeNode TreeNode5 = new TreeNode(3); + TreeNode TreeNode6 = new TreeNode(5); + + root.setLeft(TreeNode2); + root.setRight(TreeNode3); + TreeNode2.setLeft(TreeNode4); + TreeNode2.setRight(TreeNode5); + TreeNode3.setLeft(TreeNode6); + + int integers = maxDepth2(root); + + System.out.println(integers); + + } + + + + /** + * 自己思路递归法,传递当前深度,然后比较左右子树的深度 + * 速度击败100%,内存击败39.53% + * @param root + * @return + */ + public int maxDepth(TreeNode root) { + + return deep(root,0); + + } + + public int deep(TreeNode root, int depth) { + if (root == null) { + return depth; + } + depth += 1; + int leftDepth = deep(root.left, depth); + int rightDepth = deep(root.right, depth); + + return leftDepth > rightDepth ? leftDepth : rightDepth; + + + } + + + /** + * 不传深度的版本 + * @param root + * @return + */ + public int deep1(TreeNode root) { + if (root == null) { + return 0; + } + + int leftDepth = deep1(root.left); + int rightDepth = deep1(root.right); + + return (leftDepth > rightDepth ? leftDepth : rightDepth)+1; + + + } + + + /** + * 自己思路迭代法:可以使用栈的前序遍历或者Morris遍历来解决,这里尝试使用Morris遍历 + * TODO 尚且有问题,Morris前序遍历写出来了,但是不知道depth在何时加,感觉很乱,不知何时用temp何时用depth + * + * @param root + * @return + */ + public int maxDepth1(TreeNode root) { + + if(root==null){ + return 0; + } + int depth=1; + TreeNode node1=root; + TreeNode node2=null; + + while (node1!=null){ + node2=node1.left; + int tempDepth=depth; + if(node2!=null){ + //找到回到node1的节点 + while (node2.right!=null&&node2.right!=node1){ + node2=node2.right; + } + + //判断上面是从什么条件出来的 + if(node2.right==null){ + //从第一个条件出来的 + + node2.right=node1; + //放心将node1左移 + node1=node1.left; + depth+=1; + }else { + //node2已经遍历过了 + node2.right=null; + } + }else { + //左边遍历完了,往右移 + node1=node1.right; + } + + + + } + + return depth; + + } + + /** + * 自己思路迭代法:可以使用层序遍历 + * 速度击败19.47% 内存击败85.16% + * @param root + * @return + */ + public int maxDepth2(TreeNode root) { + + if(root==null){ + return 0; + } + + int depth=0; + Queue queue = new LinkedList<>(); + queue.offer(root); + + while (queue.size()>0){ + int size=queue.size(); + depth+=1; + for (int i = 0; i < size; i++) { + TreeNode poll = queue.poll(); + if(poll.left!=null)queue.offer(poll.left); + if(poll.right!= null)queue.offer(poll.right); + } + } + return depth; + } + + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/MinDepth.java b/Leecode/src/main/java/com/markilue/leecode/tree/MinDepth.java new file mode 100644 index 0000000..0d880d3 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/MinDepth.java @@ -0,0 +1,179 @@ +package com.markilue.leecode.tree; + +import org.junit.Test; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * @BelongsProject: Leecode + * @BelongsPackage: com.markilue.leecode.tree + * @Author: dingjiawen + * @CreateTime: 2022-09-22 11:28 + * @Description: TODO 力扣111题 二叉树的最小深度问题: + * 给定一个二叉树,找出其最小深度。 + * 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 + * 说明:叶子节点是指没有子节点的节点。 + * 注意:深度是从根节点到最近叶子结点的最短路径上的节点数量。左右孩子都为空的节点才是叶子结点 + * @Version: 1.0 + */ +public class MinDepth { + + @Test + public void test() { + + TreeNode root = new TreeNode(3); + TreeNode TreeNode2 = new TreeNode(9); + TreeNode TreeNode3 = new TreeNode(20); +// TreeNode TreeNode4 = new TreeNode(4); +// TreeNode TreeNode5 = new TreeNode(5); + TreeNode TreeNode6 = new TreeNode(15); + TreeNode TreeNode7 = new TreeNode(7); + + root.setRight(TreeNode3); + root.setLeft(TreeNode2); +// TreeNode2.setLeft(TreeNode4); +// TreeNode2.setRight(TreeNode5); + TreeNode3.setRight(TreeNode7); + TreeNode3.setLeft(TreeNode6); + + System.out.println(minDepth1(root)); + + } + + @Test + public void test1() { + + TreeNode root = new TreeNode(3); + TreeNode TreeNode2 = new TreeNode(9); + TreeNode TreeNode3 = new TreeNode(20); +// TreeNode TreeNode4 = new TreeNode(4); +// TreeNode TreeNode5 = new TreeNode(5); + TreeNode TreeNode6 = new TreeNode(15); + TreeNode TreeNode7 = new TreeNode(7); + +// root.setRight(TreeNode3); +// root.setLeft(TreeNode2); +// TreeNode2.setLeft(TreeNode4); +// TreeNode2.setRight(TreeNode5); +// TreeNode3.setRight(TreeNode7); +// TreeNode3.setLeft(TreeNode6); + + System.out.println(minDepth1(root)); + + } + + @Test + public void test2() { + + TreeNode root = new TreeNode(2); + TreeNode TreeNode2 = new TreeNode(3); + TreeNode TreeNode3 = new TreeNode(4); + TreeNode TreeNode4 = new TreeNode(5); + TreeNode TreeNode5 = new TreeNode(6); +// TreeNode TreeNode6 = new TreeNode(15); +// TreeNode TreeNode7 = new TreeNode(7); + +// root.setRight(TreeNode3); + root.setLeft(TreeNode2); + TreeNode2.setLeft(TreeNode3); + TreeNode3.setLeft(TreeNode4); + TreeNode4.setLeft(TreeNode5); +// TreeNode5.setLeft(TreeNode7); +// TreeNode2.setRight(TreeNode5); +// TreeNode3.setRight(TreeNode7); +// TreeNode3.setLeft(TreeNode7); + + System.out.println(minDepth(root)); + + } + + + /** + * 自己思路递归法:由于必须是叶子节点才算完,所以需要将出来的条件变为判断当前节点是否还有子节点 + * 速度击败66.79%,内存击败69.22% + * @param root + * @return + */ + public int minDepth(TreeNode root) { + + if (root == null) { + return 0; + } + + return deep1(root); + + } + + public int deep(TreeNode node) { + if (node.left == null && node.right == null) { + return 1; + } + + int deep1=Integer.MAX_VALUE; + int deep2=Integer.MAX_VALUE; + if(node.left!=null){ + deep1 = deep(node.left); + } + if(node.right!=null){ + deep2 = deep(node.right); + } + + + return (deep1 < deep2 ? deep1 : deep2) + 1; + + } + + /** + * 改进版:不需要全部遍历完,找到第一个叶子结点就可以return了 + * 似乎没有改进:速度超过66.5%,内存超过37.25% + * @param node + * @return + */ + public int deep1(TreeNode node) { + if (node.left != null && node.right != null) { + return Math.min(deep(node.left),deep(node.right))+1; + }else if(node.right != null){ + return deep(node.right)+1; + }else if(node.left != null){ + return deep(node.left)+1; + }else { + return 1; + } + } + + /** + * 自己思路层序遍历: + * 速度击败66.79%,内存击败69.22% + * @param root + * @return + */ + public int minDepth1(TreeNode root) { + + if (root == null) { + return 0; + } + + Queue treeNodes = new LinkedList<>(); + int depth=0; + + treeNodes.offer(root); + while (!treeNodes.isEmpty()){ + int size = treeNodes.size(); + depth+=1; + + for (int i = 0; i < size; i++) { + TreeNode poll = treeNodes.poll(); + //层序遍历,找到的叶子结点一定是第一个叶子结点 + if(poll.left==null&&poll.right==null){ + return depth; + } + if(poll.left!=null)treeNodes.offer(poll.left); + if(poll.right!=null)treeNodes.offer(poll.right); + } + } + + + return depth; + } +}