diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/ConvertBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/ConvertBST.java new file mode 100644 index 0000000..faece70 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/ConvertBST.java @@ -0,0 +1,198 @@ +package com.markilue.leecode.tree; + +import org.junit.Test; + +import java.util.List; +import java.util.Stack; + +/** + * /** + * + * @BelongsProject: Leecode + * @BelongsPackage: com.markilue.leecode.tree + * @Author: dingjiawen + * @CreateTime: 2022-10-11 11:32 + * @Description: TODO leecode 538题 把二叉搜索树转换为累加树: + * 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 + * 提醒一下,二叉搜索树满足下列约束条件: + * 节点的左子树仅包含键 小于 节点键的节点。 + * 节点的右子树仅包含键 大于 节点键的节点。 + * 左右子树也必须是二叉搜索树。 + * @Version: 1.0 + */ +public class ConvertBST { + + @Test + public void test() { + TreeNode root = new TreeNode(4); + TreeNode TreeNode2 = new TreeNode(1); + TreeNode TreeNode3 = new TreeNode(6); + TreeNode TreeNode4 = new TreeNode(0); + TreeNode TreeNode5 = new TreeNode(2); + TreeNode TreeNode6 = new TreeNode(5); + TreeNode TreeNode7 = new TreeNode(7); + + TreeNode TreeNode8 = new TreeNode(3); + TreeNode TreeNode9 = new TreeNode(8); + + + root.setRight(TreeNode3); + root.setLeft(TreeNode2); + TreeNode2.setLeft(TreeNode4); + TreeNode2.setRight(TreeNode5); + TreeNode3.setRight(TreeNode7); + TreeNode3.setLeft(TreeNode6); + TreeNode5.setRight(TreeNode8); + TreeNode7.setRight(TreeNode9); + + System.out.println(convertBST2(root)); + + System.out.println(root); + + } + + + @Test + public void test1() { + TreeNode root = new TreeNode(4); + TreeNode TreeNode2 = new TreeNode(2); + TreeNode TreeNode3 = new TreeNode(6); + TreeNode TreeNode4 = new TreeNode(1); + TreeNode TreeNode5 = new TreeNode(3); + TreeNode TreeNode6 = new TreeNode(5); + + root.setLeft(TreeNode2); + root.setRight(TreeNode3); + TreeNode2.setLeft(TreeNode4); + TreeNode2.setRight(TreeNode5); + TreeNode3.setLeft(TreeNode6); + + convertBST2(root); + +// System.out.println(integers); + } + + + int sum = 0; + + /** + * 递归法思路:右中左遍历即可 + * 即将中序遍历颠倒 + * 速度击败100%,内存击败79.42% + * + * @param root + * @return + */ + public TreeNode convertBST(TreeNode root) { + + if (root == null) { + return root; + } + convertBST(root.right); + + sum += root.val; + root.val = sum; + convertBST(root.left); + + return root; + + } + + /** + * 迭代法思路:右中左遍历即可 + * 即将中序遍历颠倒 + * 速度击败6.98%,内存击败5.10% + * + * @param root + * @return + */ + public TreeNode convertBST1(TreeNode root) { + + if (root == null) { + return root; + } + + int sum = 0; + + Stack stack = new Stack<>(); + + TreeNode node = root; + + while (node != null || !stack.isEmpty()) { + + if (node != null) { + stack.push(node); + node = node.right; + } else { + + TreeNode node1 = stack.pop(); + sum += node1.val; + node1.val = sum; + + node = node1.left; + + } + } + + return root; + + + } + + + /** + * 迭代法思路:右中左遍历即可 + * 即将中序遍历颠倒 + * Morris遍历:反中序遍历 + * 速度击败100%,内存击败84.39% + * + * @param root + * @return + */ + public TreeNode convertBST2(TreeNode root) { + + if (root == null) { + return root; + } + + int sum = 0; + + TreeNode pre = null; + TreeNode node = root; + + while (node != null) { + if (node.right != null) { + TreeNode node1 = node.right; + //寻找左子树最右节点 + while (node1.left != null && node1.left != node) { + node1 = node1.left; + } + + //判断是从什么条件出来的 + if (node1.left == null) { + //第一次进入该节点 + node1.left = node; + //放心将node右移 + node = node.right; + } else if (node1.left == node) { + sum += node.val; + node.val = sum; + node = node.left; + //已经遍历过了 + node1.left = null; + } + } else { + sum += node.val; + node.val = sum; + node = node.left; + } + + + } + + + return root; + + + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/tree/SortedArrayToBST.java b/Leecode/src/main/java/com/markilue/leecode/tree/SortedArrayToBST.java new file mode 100644 index 0000000..b9eaa5b --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/tree/SortedArrayToBST.java @@ -0,0 +1,117 @@ +package com.markilue.leecode.tree; + + +import org.junit.Test; +import sun.reflect.generics.tree.Tree; + +import java.util.Stack; + +/** + * @BelongsProject: Leecode + * @BelongsPackage: com.markilue.leecode.tree + * @Author: dingjiawen + * @CreateTime: 2022-09-26 10:31 + * @Description: TODO 力扣108题 将有序数组转换为二叉搜索树: + * 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 + * 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 + * @Version: 1.0 + */ +public class SortedArrayToBST { + + @Test + public void test() { + int[] nums = {-10, -3, 0, 5, 9}; + + TreeNode node = sortedArrayToBST1(nums); + System.out.println(node); + + } + + + /** + * 思路递归法:传nums和对应需要处理的序号i,一直取中间的数 + * 速度击败100%,内存击败74.53% + * + * @param nums + * @return + */ + public TreeNode sortedArrayToBST(int[] nums) { + return sorted(nums, 0, nums.length); + } + + + 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; + } + + /** + * 思路迭代法:尚且没有思路,这里使用代码随想录的思路:利用三个队列来记录节点,左索引和右指针 + * 速度击败100%,内存击败82.89% + * @param nums + * @return + */ + public TreeNode sortedArrayToBST1(int[] nums) { + + + Stack nodeStack = new Stack(); + + Stack leftStack = new Stack<>(); + Stack rightStack = new Stack<>(); + TreeNode root=new TreeNode(nums[0 + (nums.length -1) / 2]); + + leftStack.push(0); + rightStack.push(nums.length -1); + nodeStack.push(root); + + + while (!leftStack.isEmpty()) { + Integer left = leftStack.pop(); + Integer right = rightStack.pop(); + TreeNode node = nodeStack.pop(); + + + int mid = left + (right - left) / 2; + + + node.val=nums[mid]; + + + if(left<=mid-1){ + //这里的逻辑实际上就是将这边的left随便附一个值,在需要处理left时在去将left重新赋值,保证当前循环始终处理当前节点的逻辑,避免了一直需要处理左右节点,会比较麻烦,且代码重复 + //自己之前的写法实际上是计算出midLeft,midRight然后在将这个值赋给当前节点的左边和右边,在一个循坏里面需要同时处理当前节点、左节点、右节点三个逻辑, + //代码重复啰嗦 + node.left=new TreeNode(0); + leftStack.push(left); + rightStack.push(mid-1); + nodeStack.push(node.left); + } + + + if(right>=mid+1){ + node.right=new TreeNode(0); + leftStack.push(mid+1); + rightStack.push(right); + nodeStack.push(node.right); + } + + + } + + return root; + + } + + +}