leecode更新
This commit is contained in:
parent
64abd13286
commit
40313d9da9
|
|
@ -13,7 +13,7 @@ import java.util.*;
|
|||
* 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗二叉树。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class T14_BuildTree {
|
||||
public class T14_0_BuildTree {
|
||||
|
||||
|
||||
@Test
|
||||
|
|
@ -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() {
|
||||
|
|
@ -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<Integer> stack = new ArrayList<Integer>();
|
||||
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<Integer> stack = new ArrayDeque<Integer>();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ import java.util.*;
|
|||
* 3)返回合并后的二叉树。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class MergeTrees {
|
||||
public class T15_MergeTrees {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
|
@ -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() {
|
||||
|
|
@ -17,7 +17,7 @@ import java.util.Stack;
|
|||
* 3.所有左子树和右子树自身必须也是二叉搜索树。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class IsValidBST {
|
||||
public class T17_IsValidBST {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
|
@ -14,7 +14,7 @@ import java.util.Stack;
|
|||
* 差值是一个正数,其数值等于两值之差的绝对值。
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class GetMinimumDifference {
|
||||
public class T18_GetMinimumDifference {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
|
@ -19,7 +19,7 @@ import java.util.*;
|
|||
* 左子树和右子树都是二叉搜索树
|
||||
* @Version: 1.0
|
||||
*/
|
||||
public class FindMode {
|
||||
public class T19_FindMode {
|
||||
|
||||
|
||||
@Test
|
||||
|
|
@ -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(){
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.val<val){
|
||||
return searchBST(root.right, val);
|
||||
}else {
|
||||
return searchBST(root.left,val);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路:利用二叉搜索树的特性
|
||||
* 迭代法 速度击败100%,内存击败16.67%
|
||||
* @param root
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public TreeNode searchBST1(TreeNode root, int val) {
|
||||
if(root==null){
|
||||
return null;
|
||||
}
|
||||
TreeNode cur=root;
|
||||
while (cur!=null){
|
||||
if(cur.val==val){
|
||||
return cur;
|
||||
}else if(cur.val>val){
|
||||
cur=cur.left;
|
||||
}else {
|
||||
cur=cur.right;
|
||||
}
|
||||
}
|
||||
return cur;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<TreeNode> 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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<TreeNode> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Integer> 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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue