当前位置:网站首页>Leetcode刷题——二叉搜索树相关题目(98. 验证二叉搜索树、235. 二叉搜索树的最近公共祖先、1038. 从二叉搜索树到更大和树、538. 把二叉搜索树转换为累加树)
Leetcode刷题——二叉搜索树相关题目(98. 验证二叉搜索树、235. 二叉搜索树的最近公共祖先、1038. 从二叉搜索树到更大和树、538. 把二叉搜索树转换为累加树)
2022-08-04 11:06:00 【lonelyMangoo】
概念
二叉搜索树:
- 节点的左子树仅包含键 小于 节点键的节点。
- 节点的右子树仅包含键 大于 节点键的节点。
- 左右子树也必须是二叉搜索树。
而二叉搜索树的中序遍历时升序。
98. 验证二叉搜索树
题目:98. 验证二叉搜索树
思路:用中序遍历判断,当前节点是否大于之前一个。
//迭代写法
public boolean isValidBST(TreeNode root) {
Stack<TreeNode> stack = new Stack();
TreeNode cur = root;
TreeNode pre = null;
while (cur!=null || !stack.isEmpty()){
if(cur != null){
stack.add(cur);
cur = cur.left;
}
else {
cur = stack.pop();
if(pre!=null && pre.val>= cur.val){
return false;
}
//记录前一个节点
pre=cur;
cur=cur.right;
}
}
return true;
}
我一开始用的层次遍历,因为忽略了整体也要大于的情况:
也就是例子中的5、3这种情况。
当然这里也可以用递归实现,也是中序遍历并记录前一个节点
TreeNode pre=null;
public boolean isValidBST(TreeNode root) {
if(root == null ) return true;
boolean left = isValidBST(root.left);
//中序遍历操作部分
if(pre!=null && root.val <= pre.val){
return false;
}
pre = root;
boolean right =isValidBST(root.right);
return left && right;
}

我觉得递归还是比较难理解的,虽然思路是一样的但是可能不知道哪一层就出问题了,所以面试遇到还是用迭代不容易出错。
235. 二叉搜索树的最近公共祖先
题目:235. 二叉搜索树的最近公共祖先
这题只需要别人提供一个思路就能写出来:
要求的两个节点都比当前节点小,到左子树中去找
要求的两个节点都比当前节点大,到右子树中去找
如果一个比当前节点大,一个比当前节点小,就是要求的节点。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(p.val<root.val && q.val<root.val){
return lowestCommonAncestor(root.left, p, q);
}
else if(p.val>root.val && q.val>root.val){
return lowestCommonAncestor(root.right, p, q);
}
return root;
}

538. 把二叉搜索树转换为累加树
这两道题是一样的
538. 把二叉搜索树转换为累加树
1038. 从二叉搜索树到更大和树
重新建树
第一种思路是容易想到的,先中序遍历得到所有需要的值,然后再次中序遍历给树赋值。
public TreeNode bstToGst(TreeNode root) {
List<Integer> list = new ArrayList<>();
inorder(root, list);
//将list的值设置成题目需要的
for (int i = list.size() - 2; i >= 0; i--) {
list.set(i, list.get(i) + list.get(i + 1));
}
//重新赋值
build(root, list);
return root;
}
private static void build(TreeNode root, List<Integer> list) {
int i = 0;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
cur = stack.pop();
if (cur!=null){
cur.val = list.get(i++);
}
cur = cur.right;
}
}
}
private static void inorder(TreeNode root, List<Integer> list) {
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
cur = stack.pop();
//获得中序遍历的值
list.add(cur.val);
cur = cur.right;
}
}
}

递归
将中序遍历反过来就是由大到小,用一个sum记录累加即可。
int sum = 0;
public TreeNode bstToGst(TreeNode root) {
build(root);
return root;
}
//逆中序
private void build(TreeNode root){
if(root!=null){
build(root.right);
root.val+=sum;
sum=root.val;
build(root.left);
}
}

边栏推荐
猜你喜欢
随机推荐
Redis查询缓存
【LeetCode】899.有序队列
What is the terminal privilege management
语音社交app源码——具备哪些开发优势?
ThreadLocal详细分析
华为云安全云脑,让企业云化运营更放心
解决:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING
C language * Xiaobai's adventure
Win11文件类型怎么改?Win11修改文件后缀的方法
datax oracle to oracle增量同步
Small program containers accelerate the construction of an integrated online government service platform
Super Learning Method
onlyoffice设置跟踪变化trackChanges默认为对自己启动
音频编辑 合唱
Camunda overall architecture and related concepts
小程序容器加快一体化在线政务服务平台建设
Business collocations
3-5年以上的功能测试如何进阶自动化?
AWS Lambda related concepts and implementation approach
SkiaSharp 之 WPF 自绘 粒子花园(案例版)









