diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/T14_BuildTree.java b/Leecode/src/main/java/com/markilue/leecode/tree/T14_0_BuildTree.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/T14_BuildTree.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T14_0_BuildTree.java index 1748a99..73f668e 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/T14_BuildTree.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T14_0_BuildTree.java @@ -13,7 +13,7 @@ import java.util.*; * 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗二叉树。 * @Version: 1.0 */ -public class T14_BuildTree { +public class T14_0_BuildTree { @Test diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/BuildTreeII.java b/Leecode/src/main/java/com/markilue/leecode/tree/T14_1_BuildTreeII.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/BuildTreeII.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T14_1_BuildTreeII.java index 166a003..0f31f7c 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/BuildTreeII.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T14_1_BuildTreeII.java @@ -13,7 +13,7 @@ import java.util.*; * 给定两个整数数组preorder 和 inorder,其中preorder 是二叉树的先序遍历, inorder是同一棵树的中序遍历,请构造二叉树并返回其根节点。 * @Version: 1.0 */ -public class BuildTreeII { +public class T14_1_BuildTreeII { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/T14_2_ConstructMaximumBinaryTree.java b/Leecode/src/main/java/com/markilue/leecode/tree/T14_2_ConstructMaximumBinaryTree.java new file mode 100644 index 0000000..5d6cd77 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T14_2_ConstructMaximumBinaryTree.java @@ -0,0 +1,154 @@ +package com.markilue.leecode.tree; + +import com.sun.scenario.effect.Brightpass; + +import java.util.*; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.tree + *@Author: dingjiawen + *@CreateTime: 2023-01-11 11:14 + *@Description: + * TODO 力扣654 最大二叉树: + * 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: + * 创建一个根节点,其值为 nums 中的最大值。 + * 递归地在最大值 左边 的 子数组前缀上 构建左子树。 + * 递归地在最大值 右边 的 子数组后缀上 构建右子树。 + * 返回 nums 构建的 最大二叉树 。 + *@Version: 1.0 + */ +public class T14_2_ConstructMaximumBinaryTree { + + /** + * 思路:这题实际上是给了一个中序遍历,然后root的值由max确定 + * 速度击败81.34%,内存击败68.74% 2ms 时间复杂度O(n^2) + * @param nums + * @return + */ + public TreeNode constructMaximumBinaryTree(int[] nums) { + return constructTree(nums, 0, nums.length); + + } + + public TreeNode constructTree(int[] nums, int left, int right) { + if (left == right) { + return null; + } + int maxIndex = findMaxIndex(nums, left, right); + TreeNode root = new TreeNode(nums[maxIndex]); + root.left = constructTree(nums, left, maxIndex); + root.right = constructTree(nums, maxIndex + 1, right); + return root; + } + + public int findMaxIndex(int[] nums, int left, int right) { + int maxIndex = left; + for (int i = left; i < right; i++) { + if (nums[maxIndex] < nums[i]) { + maxIndex = i; + } + } + return maxIndex; + } + + + /** + * 官方单调栈解法: + * 时间复杂度O(N) + * 速度击败5.7%,内存击败82.36% 20ms + * @param nums + * @return + */ + public TreeNode constructMaximumBinaryTree1(int[] nums) { + int n = nums.length; + List stack = new ArrayList(); + TreeNode[] tree = new TreeNode[n]; + for (int i = 0; i < n; ++i) { + tree[i] = new TreeNode(nums[i]); + while (!stack.isEmpty() && nums[i] > nums[stack.get(stack.size() - 1)]) { + tree[i].left = tree[stack.get(stack.size() - 1)]; + stack.remove(stack.size() - 1); + } + if (!stack.isEmpty()) { + tree[stack.get(stack.size() - 1)].right = tree[i]; + } + stack.add(i); + } + return tree[stack.get(0)]; + } + + + /** + * 官方单调栈容易理解版: + * TODO + * 核心在于维护一个单调栈,这个栈单调递增; + * 1)如果来的数大于栈里面的数,又因为来的数的索引i一定大于栈的数的索引;所以栈里面的数的右边界应该是来的这个数(所以栈里数应该是来数的左子树);对应于while内容 + * 2)如果来的数小于栈里面的数,又因为来的数的索引i一定大于栈的数的索引;所以来的这个数的左边界应该是栈里面这个数(所以是栈里数的左子树);对应于if内容 + * @param nums + * @return + */ + public TreeNode constructMaximumBinaryTree2(int[] nums) { + int n = nums.length; + Deque stack = new ArrayDeque(); + int[] left = new int[n]; + int[] right = new int[n]; + Arrays.fill(left, -1); + Arrays.fill(right, -1); + TreeNode[] tree = new TreeNode[n]; + for (int i = 0; i < n; ++i) { + tree[i] = new TreeNode(nums[i]); + while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) { + right[stack.pop()] = i; + } + if (!stack.isEmpty()) { + left[i] = stack.peek(); + } + stack.push(i); + } + + TreeNode root = null; + for (int i = 0; i < n; ++i) { + if (left[i] == -1 && right[i] == -1) { + //最大的那个数,一定一直在栈里面所以left和right一定没有赴过值 + root = tree[i]; + } else if (right[i] == -1 || (left[i] != -1 && nums[left[i]] < nums[right[i]])) { + tree[left[i]].right = tree[i];//这个数的左边界的右子树应该是这个数 + } else { + tree[right[i]].left = tree[i]; + } + } + return root; + } + + /** + * 官方最快:与本人思路一致 + * @param nums + * @return + */ + public TreeNode constructMaximumBinaryTree3(int[] nums) { + return constructTree1(nums, 0, nums.length); + } + + public TreeNode constructTree1(int[] nums, int leftIndex, int rightIndex) { + if (rightIndex - leftIndex < 1) { + return null; + } + if (rightIndex - leftIndex == 1) { + return new TreeNode(nums[leftIndex]); + } + int maxIndex = leftIndex; + int maxVal = nums[maxIndex]; + for (int i = leftIndex + 1; i < rightIndex; i++) { + if (nums[i] > maxVal) { + maxVal = nums[i]; + maxIndex = i; + } + } + TreeNode root = new TreeNode(maxVal); + root.left = constructTree1(nums, leftIndex, maxIndex); + root.right = constructTree1(nums, maxIndex + 1, rightIndex); + return root; + } + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/MergeTrees.java b/Leecode/src/main/java/com/markilue/leecode/tree/T15_MergeTrees.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/MergeTrees.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T15_MergeTrees.java index 8230948..34a201c 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/MergeTrees.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T15_MergeTrees.java @@ -18,7 +18,7 @@ import java.util.*; * 3)返回合并后的二叉树。 * @Version: 1.0 */ -public class MergeTrees { +public class T15_MergeTrees { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/SearchBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/T16_SearchBST.java similarity index 98% rename from Leecode/src/main/java/com/markilue/leecode/tree/SearchBST.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T16_SearchBST.java index 11fa7cb..dcb3632 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/SearchBST.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T16_SearchBST.java @@ -12,7 +12,7 @@ import org.junit.Test; * 你需要在 BST 中找到节点值等于val的节点。 返回以该节点为根的子树。 如果节点不存在,则返回null。 * @Version: 1.0 */ -public class SearchBST { +public class T16_SearchBST { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/IsValidBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/T17_IsValidBST.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/IsValidBST.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T17_IsValidBST.java index 352330b..7d87ade 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/IsValidBST.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T17_IsValidBST.java @@ -17,7 +17,7 @@ import java.util.Stack; * 3.所有左子树和右子树自身必须也是二叉搜索树。 * @Version: 1.0 */ -public class IsValidBST { +public class T17_IsValidBST { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/GetMinimumDifference.java b/Leecode/src/main/java/com/markilue/leecode/tree/T18_GetMinimumDifference.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/GetMinimumDifference.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T18_GetMinimumDifference.java index eec3896..cabf5ec 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/GetMinimumDifference.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T18_GetMinimumDifference.java @@ -14,7 +14,7 @@ import java.util.Stack; * 差值是一个正数,其数值等于两值之差的绝对值。 * @Version: 1.0 */ -public class GetMinimumDifference { +public class T18_GetMinimumDifference { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/FindMode.java b/Leecode/src/main/java/com/markilue/leecode/tree/T19_FindMode.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/FindMode.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T19_FindMode.java index 714598b..e50eec0 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/FindMode.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T19_FindMode.java @@ -19,7 +19,7 @@ import java.util.*; * 左子树和右子树都是二叉搜索树 * @Version: 1.0 */ -public class FindMode { +public class T19_FindMode { @Test diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T14_BuildTree.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T14_0_BuildTree.java similarity index 98% rename from Leecode/src/main/java/com/markilue/leecode/tree/second/T14_BuildTree.java rename to Leecode/src/main/java/com/markilue/leecode/tree/second/T14_0_BuildTree.java index 5b9a1ef..6a4a880 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/second/T14_BuildTree.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T14_0_BuildTree.java @@ -16,7 +16,7 @@ import java.util.Arrays; * postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 *@Version: 1.0 */ -public class T14_BuildTree { +public class T14_0_BuildTree { @Test public void test(){ diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T14_1_BuildTreeII.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T14_1_BuildTreeII.java new file mode 100644 index 0000000..aa2d90e --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T14_1_BuildTreeII.java @@ -0,0 +1,92 @@ +package com.markilue.leecode.tree.second; + +import com.markilue.leecode.tree.TreeNode; +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.tree.second + *@Author: dingjiawen + *@CreateTime: 2023-01-11 10:03 + *@Description: + * TODO 力扣105题 从前序与中序遍历序列构造二叉树: + * 给定两个整数数组 preorder 和 inorder , + * 其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历, + * 请构造二叉树并返回其根节点。 + *@Version: 1.0 + */ +public class T14_1_BuildTreeII { + + @Test + public void test() { + int[] inorder = {9, 3, 15, 20, 7}, preorder = {3, 9, 20, 15, 7}; + System.out.println(buildTree(preorder, inorder)); + } + + /** + * 思路:T14_0类似,只不过这里是从头开始找root + * 速度击败43.48%,内存击败80.45% 3ms + * @param preorder + * @param inorder + * @return + */ + public TreeNode buildTree(int[] preorder, int[] inorder) { + return build(preorder, inorder, 0, preorder.length, 0, inorder.length); + } + + public TreeNode build(int[] preorder, int[] inorder, int preLeft, int preRight, int inLeft, int inRight) { + int length = preRight - preLeft; + if (length == 0) { + return null; + } + TreeNode root = new TreeNode(preorder[preLeft]); + int boundary = inLeft; + for (; boundary < inRight; boundary++) { + if (inorder[boundary] == root.val) { + break; + } + } + boundary = boundary - inLeft; + root.left = build(preorder, inorder, preLeft + 1, preLeft + 1 + boundary, inLeft, inLeft + boundary); + root.right = build(preorder, inorder, preLeft + 1 + boundary, preRight, inLeft + boundary + 1, inRight); + return root; + + } + + + /** + * 官方最快:思路类似,可能快在不传pre的,直接通过i++来获取 + * 速度击败100%,内存击败53.29% 0ms + */ + public int i = 0; + public TreeNode buildTree1(int[] preorder, int[] inorder) { + TreeNode root = buildTreeChild(preorder, inorder, 0, inorder.length - 1); + return root; + + } + + public TreeNode buildTreeChild(int[] preorder, int[] inorder, + int inbegin, int inend) { + if (inbegin > inend) { + return null; + } + TreeNode root = new TreeNode(preorder[i]); + //找到当前根,在中序遍历的位置 + int rootIndex = findIndex(inorder, inbegin, inend, preorder[i]); + i++; + root.left = buildTreeChild(preorder, inorder, inbegin, rootIndex - 1); + root.right = buildTreeChild(preorder, inorder, rootIndex + 1, inend); + return root; + } + + private int findIndex(int[] inorder, int inbegin, int end, int key) { + int rootIndex = 0; + while (end >= inbegin) { + if (inorder[end] == key) { + return end; + } + end--; + } + return -1; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T15_MergeTrees.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T15_MergeTrees.java new file mode 100644 index 0000000..23625b4 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T15_MergeTrees.java @@ -0,0 +1,69 @@ +package com.markilue.leecode.tree.second; + +import com.markilue.leecode.tree.TreeNode; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.tree.second + *@Author: dingjiawen + *@CreateTime: 2023-01-11 12:11 + *@Description: + * TODO 力扣617题 合并二叉树: + * 给你两棵二叉树: root1 和 root2 。 + * 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。 + * 你需要将这两棵树合并成一棵新二叉树。合并的规则是: + * 如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值; + * 否则,不为 null 的节点将直接作为新二叉树的节点。 + * 返回合并后的二叉树。 + * 注意: 合并过程必须从两个树的根节点开始。 + *@Version: 1.0 + */ +public class T15_MergeTrees { + + /** + * 思路:递归法 + * 速度击败100%,内存击败35.5% + * @param root1 + * @param root2 + * @return + */ + public TreeNode mergeTrees(TreeNode root1, TreeNode root2) { + TreeNode root; + if (root1 == null && root2 == null) { + return null; + } else if (root1 == null) { + root= new TreeNode(root2.val); + root.left=mergeTrees(null,root2.left); + root.right=mergeTrees(null,root2.right); + } else if (root2 == null) { + root = new TreeNode(root1.val); + root.left=mergeTrees(root1.left,null); + root.right=mergeTrees(root1.right,null); + } else { + root = new TreeNode(root1.val+root2.val); + root.left=mergeTrees(root1.left,root2.left); + root.right=mergeTrees(root1.right,root2.right); + } + + return root; + } + + /** + * 自己以前写的优秀写法 + * @param root1 + * @param root2 + * @return + */ + public TreeNode mergeTrees1(TreeNode root1, TreeNode root2) { + if (root1 == null) { + return root2; + } else { + if (root2 != null) { + root1.val = root1.val + root2.val; + root1.left=mergeTrees1(root1.left,root2.left); + root1.right=mergeTrees1(root1.right,root2.right); + } + return root1; + } + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T16_SearchBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T16_SearchBST.java new file mode 100644 index 0000000..bc172df --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T16_SearchBST.java @@ -0,0 +1,66 @@ +package com.markilue.leecode.tree.second; + +import com.markilue.leecode.tree.TreeNode; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.tree.second + *@Author: dingjiawen + *@CreateTime: 2023-01-12 12:11 + *@Description: + * TODO 二刷题700 二叉搜索树中的搜索: + * 给定二叉搜索树(BST)的根节点 root 和一个整数值 val。 + * 你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。 + *@Version: 1.0 + */ +public class T16_SearchBST { + + + /** + * 思路:利用二叉搜索树的特性 + * 递归法 速度击败100%,内存击败16.67% + * @param root + * @param val + * @return + */ + public TreeNode searchBST(TreeNode root, int val) { + if(root==null){ + return null; + } + if(root.val==val){ + return root; + }else if(root.valval){ + cur=cur.left; + }else { + cur=cur.right; + } + } + return cur; + + + } + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T17_IsValidBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T17_IsValidBST.java new file mode 100644 index 0000000..df29a99 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T17_IsValidBST.java @@ -0,0 +1,86 @@ +package com.markilue.leecode.tree.second; + +import com.markilue.leecode.tree.TreeNode; +import org.junit.Test; + +import java.util.Stack; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.tree.second + *@Author: dingjiawen + *@CreateTime: 2023-01-12 12:27 + *@Description: + * TODO 二刷力扣98题 验证二叉搜索树: + * 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 + * 有效 二叉搜索树定义如下: + * 节点的左子树只包含 小于 当前节点的数。 + * 节点的右子树只包含 大于 当前节点的数。 + * 所有左子树和右子树自身必须也是二叉搜索树。 + *@Version: 1.0 + */ +public class T17_IsValidBST { + + @Test + public void test(){ + System.out.println(Integer.MAX_VALUE); + } + + /** + * 思路:需要注意不是左右子树满足就行,而是整个左右子树都需要满足 + * 速度击败100%,内存击败85.63% + * @param root + * @return + */ + public boolean isValidBST(TreeNode root) { + return isValid(root, Long.MIN_VALUE, Long.MAX_VALUE); + } + + /** + * 当前节点需要满足左右边界 + * @param root + * @param leftThreshold + * @param rightThreshold + * @return + */ + public boolean isValid(TreeNode root, long leftThreshold, long rightThreshold) { + if (root == null) { + return true; + } + if (root.val <= leftThreshold || root.val >= rightThreshold) { + return false; + } + return isValid(root.left, leftThreshold, root.val) && isValid(root.right, root.val, rightThreshold); + + } + + + /** + * 递归法中序遍历即可:前面的节点一定要小于当前的节点即可 + * 速度击败19.10%,内存击败13.11% + * @param root + * @return + */ + public boolean isValidBST1(TreeNode root) { + if (root == null) { + return false; + } + + Stack stack = new Stack<>(); + TreeNode pre = null;//记录前一个节点 + TreeNode cur = root; + while (!stack.isEmpty() || cur != null) { + if (cur != null) { + stack.push(cur); + cur=cur.left; + } else { + cur = stack.pop(); + if (pre != null && cur.val <= pre.val) return false; + pre = cur;//保存访问的前一个节点 + cur = cur.right; + } + } + return true; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T18_GetMinimumDifference.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T18_GetMinimumDifference.java new file mode 100644 index 0000000..46954a1 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T18_GetMinimumDifference.java @@ -0,0 +1,69 @@ +package com.markilue.leecode.tree.second; + +import com.markilue.leecode.tree.TreeNode; + +import java.util.Stack; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.tree.second + *@Author: dingjiawen + *@CreateTime: 2023-01-12 12:46 + *@Description: + * TODO 力扣530 二叉搜索树的最小绝对差: + * 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 。 + * 差值是一个正数,其数值等于两值之差的绝对值。 + *@Version: 1.0 + */ +public class T18_GetMinimumDifference { + + /** + * 思路:二叉搜索树特性决定了,最小绝对差一定是两个连续中序遍历节点的差值 + * 速度击败100%,内存击败77.8% + * @param root + * @return + */ + int min=Integer.MAX_VALUE; + TreeNode pre=null; + public int getMinimumDifference(TreeNode root) { + travel(root); + return min; + } + public void travel(TreeNode root) { + if(root==null){ + return; + } + travel(root.left); + if(pre!=null&&min>root.val-pre.val){ + min=root.val-pre.val; + } + pre=root; + travel(root.right); + } + + + /** + * 迭代法,仍然是中序遍历,实际上与上面的递归无差异 + */ + Stack stack; + public int getMinimumDifference1(TreeNode root) { + if (root == null) return 0; + stack = new Stack<>(); + TreeNode cur = root; + int result = Integer.MAX_VALUE; + while (cur != null || !stack.isEmpty()) { + if (cur != null) { + stack.push(cur); // 将访问的节点放进栈 + cur = cur.left; // 左 + }else { + cur = stack.pop(); + if (pre != null) { // 中 + result = Math.min(result, cur.val - pre.val); + } + pre = cur; + cur = cur.right; // 右 + } + } + return result; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T19_FindMode.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T19_FindMode.java new file mode 100644 index 0000000..4f032c5 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T19_FindMode.java @@ -0,0 +1,77 @@ +package com.markilue.leecode.tree.second; + +import com.markilue.leecode.tree.TreeNode; + +import java.util.ArrayList; +import java.util.List; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.tree.second + *@Author: dingjiawen + *@CreateTime: 2023-01-12 13:05 + *@Description: + * TODO 力扣501 二叉搜索树中的众数: + * 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 + * 如果树中有不止一个众数,可以按 任意顺序 返回。 + * 假定 BST 满足如下定义: + * 结点左子树中所含节点的值 小于等于 当前节点的值 + * 结点右子树中所含节点的值 大于等于 当前节点的值 + * 左子树和右子树都是二叉搜索树 + *@Version: 1.0 + */ +public class T19_FindMode { + + /** + * 思路:由于二叉搜索树的中序遍历的特性,相同的数应该是连在一起的 + * 速度击败100%,内存击败85.48% + * @param root + * @return + */ + TreeNode pre = null; + int maxTime = 0; + int curTime = 0; + List result = new ArrayList<>(); + + public int[] findMode(TreeNode root) { + find(root); + //最后一次如果相等就还是不会进 + if (maxTime == curTime) { + result.add(pre.val); + } else if (maxTime < curTime) { + maxTime = curTime; + result.clear(); + result.add(pre.val); + } + int[] nums = new int[result.size()]; + for (int i = 0; i < nums.length; i++) { + nums[i]=result.get(i); + } + return nums; + + } + + public void find(TreeNode root) { + if (root == null) { + return; + } + find(root.left); + if (pre == null || pre.val == root.val) { + curTime++; + }else { + if (maxTime == curTime) { + result.add(pre.val); + } else if (maxTime < curTime) { + maxTime = curTime; + result.clear(); + result.add(pre.val); + } + curTime = 1; + } + + + + pre=root; + find(root.right); + } +}