leecode更新

This commit is contained in:
markilue 2022-10-11 18:22:41 +08:00
parent f55bd38ecd
commit d8f403cc14
2 changed files with 315 additions and 0 deletions

View File

@ -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<TreeNode> 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;
}
}

View File

@ -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<TreeNode> nodeStack = new Stack<TreeNode>();
Stack<Integer> leftStack = new Stack<>();
Stack<Integer> 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;
}
}