diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/TrimBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/T24_TrimBST.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/TrimBST.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T24_TrimBST.java index e1ee3c8..61530e6 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/TrimBST.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T24_TrimBST.java @@ -17,7 +17,7 @@ import static com.markilue.leecode.tree.T03_InorderTraversal.inorderTraversal1; * 所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。 * @Version: 1.0 */ -public class TrimBST { +public class T24_TrimBST { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/SortedArrayToBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/T25_SortedArrayToBST.java similarity index 98% rename from Leecode/src/main/java/com/markilue/leecode/tree/SortedArrayToBST.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T25_SortedArrayToBST.java index b9eaa5b..b781ae6 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/SortedArrayToBST.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T25_SortedArrayToBST.java @@ -16,7 +16,7 @@ import java.util.Stack; * 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 * @Version: 1.0 */ -public class SortedArrayToBST { +public class T25_SortedArrayToBST { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/ConvertBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/T26_ConvertBST.java similarity index 99% rename from Leecode/src/main/java/com/markilue/leecode/tree/ConvertBST.java rename to Leecode/src/main/java/com/markilue/leecode/tree/T26_ConvertBST.java index faece70..8c5e6d9 100644 --- a/Leecode/src/main/java/com/markilue/leecode/tree/ConvertBST.java +++ b/Leecode/src/main/java/com/markilue/leecode/tree/T26_ConvertBST.java @@ -20,7 +20,7 @@ import java.util.Stack; * 左右子树也必须是二叉搜索树。 * @Version: 1.0 */ -public class ConvertBST { +public class T26_ConvertBST { @Test public void test() { diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T24_TrimBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T24_TrimBST.java new file mode 100644 index 0000000..5d38481 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T24_TrimBST.java @@ -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.valhigh)){ + if(root.valhigh){ + cur.right=cur.right.left; + } + //处理完毕,安心将cur右移,继续判断其左节点会不会超过 + cur=cur.right; + //这里不需要判断左节点,因为root在区间内,那么右子树最小也就是root,所以不会超过其左界 + } + //全部处理完毕,安心返回root + return root; + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/second/T25_SortedArrayToBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/second/T25_SortedArrayToBST.java new file mode 100644 index 0000000..1453eea --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/second/T25_SortedArrayToBST.java @@ -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 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; + + + } + + +}