随想录日记part19
t i m e : time: time: 2024.03.14
主要内容:今天的主要内容是二叉树的第七部分,主要涉及修剪二叉搜索树 ;将有序数组转换为二叉搜索树;把二叉搜索树转换为累加树。
Topic1修剪二叉搜索树
题目:
给你二叉搜索树的根节点 r o o t root root,同时给定最小边界 l o w low low 和最大边界 h i g h high high。通过修剪二叉搜索树,使得所有节点的值在 [ l o w , h i g h ] [low, high] [low,high] 中。修剪树不应该改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在唯一的答案 。所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
示例:
输入:
r
o
o
t
=
[
3
,
0
,
4
,
n
u
l
l
,
2
,
n
u
l
l
,
n
u
l
l
,
1
]
,
l
o
w
=
1
,
h
i
g
h
=
3
root = [3,0,4,null,2,null,null,1], low = 1, high = 3
root=[3,0,4,null,2,null,null,1],low=1,high=3
输出:
[
3
,
2
,
n
u
l
l
,
1
]
[3,2,null,1]
[3,2,null,1]
思路:
递归三部曲如下:
- 确定递归函数返回值以及参数
TreeNode trimBST(TreeNode root, int low, int high)
- 确定终止条件:修剪的操作并不是在终止条件上进行的,所以就是遇到空节点返回就可以了。
if (root == null)return null;
- 确定单层递归的逻辑
1.如果 r o o t root root(当前节点)的元素小于 l o w low low 的数值,那么应该递归右子树,并返回右子树符合条件的结点。
2.如果 r o o t root root(当前节点)的元素大于 h i g h high high的,那么应该递归左子树,并返回左子树符合条件的头结点。
3.接下来要将下一层处理完左子树的结果赋给 r o o t . l e f t root.left root.left,处理完右子树的结果赋给 r o o t . r i g h t root.right root.right ,最后返回root节点。
if (root.val < low) {
return trimBST(root.right, low, high);
} else if (root.val > high) {
return trimBST(root.left, low, high);
} else {
TreeNode left = trimBST(root.left, low, root.val - 1);
TreeNode right = trimBST(root.right, root.val + 1, high);
root.left = left;
root.right = right;
return root;
}
完整代码如下:
class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) {
if (root == null)
return null;
if (root.val < low) {
return trimBST(root.right, low, high);
} else if (root.val > high) {
return trimBST(root.left, low, high);
} else {
TreeNode left = trimBST(root.left, low, root.val - 1);
TreeNode right = trimBST(root.right, root.val + 1, high);
root.left = left;
root.right = right;
return root;
}
}
}
Topic2将有序数组转换为二叉搜索树
题目:
给你一个整数数组 n u m s nums nums ,其中元素已经按升序排列,请你将其转换为一棵平衡二叉搜索树。
输入:
n
u
m
s
=
[
−
10
,
−
3
,
0
,
5
,
9
]
nums = [-10,-3,0,5,9]
nums=[−10,−3,0,5,9]
输出:
[
0
,
−
3
,
9
,
−
10
,
n
u
l
l
,
5
]
[0,-3,9,-10,null,5]
[0,−3,9,−10,null,5]
解释: [0,-10,5,null,-3,null,9] 也将被视为正确答案:
思路: 为了保证是平衡二叉树,我们使用二分原始数组进行递归建立。
递归三部曲:
- 确定递归函数参数以及返回值
TreeNode sort(int[] nums, int start, int end)
- 确定终止条件
这里定义的是左闭右闭的区间,所以当区间 s t a r t > e n d start > end start>end 的时候,就是空节点了
if (start > end)
return null;
- 确定单层递归的逻辑
if (start == end) {
TreeNode tem = new TreeNode(nums[start]);
return tem;
} else {
int mid = (start + end) / 2;
if (mid == start) {
TreeNode root = new TreeNode(nums[mid]);
root.right = sort(nums, mid + 1, end);
return root;
} else {
TreeNode root = new TreeNode(nums[mid]);
root.left = sort(nums, start, mid - 1);
root.right = sort(nums, mid + 1, end);
return root;
}
}
总体代码如下: 递归法:
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return sort(nums, 0, nums.length - 1);
}
private TreeNode sort(int[] nums, int start, int end) {
if (start > end)
return null;
if (start == end) {
TreeNode tem = new TreeNode(nums[start]);
return tem;
} else {
int mid = (start + end) / 2;
if (mid == start) {
TreeNode root = new TreeNode(nums[mid]);
root.right = sort(nums, mid + 1, end);
return root;
} else {
TreeNode root = new TreeNode(nums[mid]);
root.left = sort(nums, start, mid - 1);
root.right = sort(nums, mid + 1, end);
return root;
}
}
}
}
Topic3把二叉搜索树转换为累加树
题目:
给出二叉搜索树的根节点,该树的节点值各不相同,请你将其转换为累加树( G r e a t e r S u m T r e e Greater\ Sum\ Tree Greater Sum Tree),使每个节点 n o d e node node 的新值等于原树中大于或等于 n o d e . v a l node.val node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
- 节点的左子树仅包含键 小于 节点键的节点。
- 节点的右子树仅包含键 大于 节点键的节点。
- 左右子树也必须是二叉搜索树
示例:
输入:
[
4
,
1
,
6
,
0
,
2
,
5
,
7
,
n
u
l
l
,
n
u
l
l
,
n
u
l
l
,
3
,
n
u
l
l
,
n
u
l
l
,
n
u
l
l
,
8
]
[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
输出:
[
30
,
36
,
21
,
36
,
35
,
26
,
15
,
n
u
l
l
,
n
u
l
l
,
n
u
l
l
,
33
,
n
u
l
l
,
n
u
l
l
,
n
u
l
l
,
8
]
[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
思路:
递归三部曲:
- 确定递归函数参数以及返回值
void trans(TreeNode root)
int pre;
- 确定终止条件
遇到空返回
if(root==null) return;
- 确定单层递归的逻辑
按照右中左递归就行
trans(root.right);//右边
root.val=pre+root.val;//中
pre=root.val;
trans(root.left);//左边
总体代码如下: 递归法:
class Solution {
int pre;
private void trans(TreeNode root) {
if (root == null)
return;
trans(root.right);// 右边
root.val = pre + root.val;// 中
pre = root.val;
trans(root.left);// 左边
}
public TreeNode convertBST(TreeNode root) {
pre = 0;
trans(root);
return root;
}
}