leecode更新
This commit is contained in:
parent
3524d0c2a9
commit
989eeb2243
|
|
@ -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() {
|
||||||
|
|
@ -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() {
|
||||||
|
|
@ -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() {
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue