leecode更新

This commit is contained in:
markilue 2023-01-30 13:13:34 +08:00
parent 3524d0c2a9
commit 989eeb2243
6 changed files with 296 additions and 3 deletions

View File

@ -17,7 +17,7 @@ import static com.markilue.leecode.tree.T03_InorderTraversal.inorderTraversal1;
* 所以结果应当返回修剪好的二叉搜索树的新的根节点注意根节点可能会根据给定的边界发生改变 * 所以结果应当返回修剪好的二叉搜索树的新的根节点注意根节点可能会根据给定的边界发生改变
* @Version: 1.0 * @Version: 1.0
*/ */
public class TrimBST { public class T24_TrimBST {
@Test @Test
public void test() { public void test() {

View File

@ -16,7 +16,7 @@ import java.util.Stack;
* 高度平衡 二叉树是一棵满足每个节点的左右两个子树的高度差的绝对值不超过 1 的二叉树 * 高度平衡 二叉树是一棵满足每个节点的左右两个子树的高度差的绝对值不超过 1 的二叉树
* @Version: 1.0 * @Version: 1.0
*/ */
public class SortedArrayToBST { public class T25_SortedArrayToBST {
@Test @Test
public void test() { public void test() {

View File

@ -20,7 +20,7 @@ import java.util.Stack;
* 左右子树也必须是二叉搜索树 * 左右子树也必须是二叉搜索树
* @Version: 1.0 * @Version: 1.0
*/ */
public class ConvertBST { public class T26_ConvertBST {
@Test @Test
public void test() { public void test() {

View File

@ -0,0 +1,101 @@
package com.markilue.leecode.tree.second;
import com.markilue.leecode.tree.TreeNode;
import com.markilue.leecode.tree.TreeUtils;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.tree.second
*@Author: dingjiawen
*@CreateTime: 2023-01-30 10:59
*@Description:
* TODO 二刷力扣669题 修剪二叉搜索树:
* 给你二叉搜索树的根节点 root 同时给定最小边界low 和最大边界 high
* 通过修剪二叉搜索树使得所有节点的值在[low, high]
* 修剪树 不应该 改变保留在树中的元素的相对结构 (如果没有被移除原有的父代子代关系都应当保留)
* 可以证明存在 唯一的答案
* 所以结果应当返回修剪好的二叉搜索树的新的根节点注意根节点可能会根据给定的边界发生改变
*@Version: 1.0
*/
public class T24_TrimBST {
@Test
public void test() {
TreeNode root = TreeUtils.structureTree(Arrays.asList(3, 1, 4, null, 2), 0);
trimBST(root, 3, 4);
TreeUtils.printTreeByLevel(root);
}
/**
* 思路:找到一个符合范围的就删除然后再次寻找可以但是效率太慢了,使用下面这种方式
* 速度击败100%内存击败31.92%
* @param root
* @param low
* @param high
* @return
*/
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null) {
return null;
} else if (root.val < low) {
return trimBST(root.right, low, high);
} else if (root.val > high) {
return trimBST(root.left, low, high);
}
root.left = trimBST(root.left, low, high);
root.right = trimBST(root.right, low, high);
return root;
}
/**
* 代码随想录提供的一种非递归法思路,将步骤可以总结为:
* 1.找到第一个在区间范围内的
* 2.处理其左节点范围之外的
* 3.处理其右节点范围之外的
* 之所以可以这么做是因为root规定了左子树的右极限和右子树的左极限
* @param root
* @param low
* @param high
* @return
*/
public TreeNode trimBST1(TreeNode root, int low, int high) {
if(root==null)return null;
//处理头结点让root移动到一个在区间内的数
while (root!=null&&(root.val<low||root.val>high)){
if(root.val<low)root=root.right;
else root= root.left;
}
//找了第一个不是的数
//处理其左节点
TreeNode cur=root;
while (cur!=null){
while (cur.left!=null&&cur.left.val<low){
cur.left=cur.left.right;
}
//处理完毕安心将cur左移继续判断其左节点会不会超过
cur=cur.left;
//这里不需要判断右节点因为root在区间内那么左子树最大也就是root所以不会超过其右界
}
//在处理其右节点
cur=root;
while (cur!=null){
while (cur.right!=null&&cur.right.val>high){
cur.right=cur.right.left;
}
//处理完毕安心将cur右移继续判断其左节点会不会超过
cur=cur.right;
//这里不需要判断左节点因为root在区间内那么右子树最小也就是root所以不会超过其左界
}
//全部处理完毕安心返回root
return root;
}
}

View File

@ -0,0 +1,65 @@
package com.markilue.leecode.tree.second;
import com.markilue.leecode.tree.TreeNode;
import com.markilue.leecode.tree.TreeUtils;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.tree.second
*@Author: dingjiawen
*@CreateTime: 2023-01-30 11:36
*@Description:
* TODO 二刷力扣108题 将有序数组转换为二叉搜索树
* 给你一个整数数组 nums 其中元素已经按 升序 排列请你将其转换为一棵 高度平衡 二叉搜索树
* 高度平衡 二叉树是一棵满足每个节点的左右两个子树的高度差的绝对值不超过 1 的二叉树
*@Version: 1.0
*/
public class T25_SortedArrayToBST {
@Test
public void test() {
int[] nums = {-10, -3, 0, 5, 9};
TreeUtils.printTreeByLevel(sortedArrayToBST(nums));
}
public TreeNode sortedArrayToBST(int[] nums) {
return build(nums, 0, nums.length-1);
}
public TreeNode build(int[] nums, int start, int end) {
if(start>end)return null;
if (start == end) return new TreeNode(nums[start]);
int mid = start + ((end - start) >> 1);
TreeNode root = new TreeNode(nums[mid]);
root.left = build(nums, start, mid - 1);
root.right = build(nums, mid + 1, end);
return root;
}
/**
* 这是一种保持左闭右开的方式由于(right - left) / 2是奇数一定会舍
* 所以left + (right - left) / 2<right
* @param nums
* @param left
* @param right
* @return
*/
public TreeNode sorted(int[] nums, int left, int right) {
if (left == right) {
return null;
}
int mid = left + (right - left) / 2;
TreeNode node = new TreeNode(nums[mid]);
node.left = sorted(nums, left, mid);
node.right = sorted(nums, mid + 1, right);
return node;
}
}

View File

@ -0,0 +1,127 @@
package com.markilue.leecode.tree.second;
import com.markilue.leecode.tree.TreeNode;
import com.markilue.leecode.tree.TreeUtils;
import org.junit.Test;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Stack;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.tree.second
*@Author: dingjiawen
*@CreateTime: 2023-01-30 12:02
*@Description:
* TODO 二刷力扣538题 把二叉搜索树转为累加树
* 给出二叉 搜索 树的根节点该树的节点值各不相同请你将其转换为累加树Greater Sum Tree
* 使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和
* 提醒一下二叉搜索树满足下列约束条件
* 节点的左子树仅包含键 小于 节点键的节点
* 节点的右子树仅包含键 大于 节点键的节点
* 左右子树也必须是二叉搜索树
*@Version: 1.0
*/
public class T26_ConvertBST {
@Test
public void test() {
TreeNode root = TreeUtils.structureTree(Arrays.asList(4, 1, 6, 0, 2, 5, 7, null, null, null, 3, null, null, null, 8), 0);
convertBST2(root);
TreeUtils.printTreeByLevel(root);
}
int sum = 0;
public TreeNode convertBST(TreeNode root) {
if (root == null) {
return root;
}
root.right = convertBST(root.right);
sum += root.val;
root.val = sum;
root.left = convertBST(root.left);
return root;
}
/**
* 迭代法
* @param root
* @return
*/
public TreeNode convertBST1(TreeNode root) {
if (root == null) {
return root;
}
Deque<TreeNode> stack = new LinkedList<>();
int pre = 0;
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.right;
} else {
TreeNode node = stack.pop();
node.val += pre;
pre = node.val;
cur = node.left;
}
}
return root;
}
/**
* Morris遍历法
* @param root
* @return
*/
public TreeNode convertBST2(TreeNode root) {
if (root == null) {
return root;
}
TreeNode cur = root;
TreeNode pre;
int sum=0;
while (cur != null) {
//寻找其右子树的最左节点
pre = cur.right;
if (pre != null) {
while (pre.left != null && pre.left != cur) {
pre = pre.left;
}
//判断是从什么条件出来的
if (pre.left == null) {
//第一遍历到
pre.left = cur;
//放心将其右移
cur = cur.right;
continue;
}
else if (pre.left == cur) {
//第二次遍历到
cur.val+=sum;
sum=cur.val;
cur=cur.left;
pre.left=null;
}
}else {
cur.val+=sum;
sum=cur.val;
cur=cur.left;
}
}
return root;
}
}