目录
108.将有序数组转化为二叉搜索树
BST:
二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树。
二叉搜索树:一棵二叉树,可以为空;如果不为空,满足以下性质:
- 非空左子树的所有键值小于其根结点的键值。
- 非空右子树的所有键值大于其根结点的键值。
- 左、右子树都是二叉搜索树。
首先,了解二叉搜索树BST及高度平衡二叉搜索树AVL,看了两分钟b站的视频有了思路,这题和前面做过的根据前序和中序构造二叉树已经种种分治类题目很像,有了思路自己基本能写出来:
因为数组是有序的,要求构造高度平衡的BST,因此我们找到数组的中间节点作为根节点,进行数组的划分,然后再根据左右区间进行相同的递归操作。构造时递归调用返回的是节点值,与遍历时不同。
class Solution {
//private TreeNode root;
public TreeNode sortedArrayToBST(int[] nums) {
int length = nums.length;
return buildSubAVL(nums, 0, length-1);
//return root;
}
private TreeNode buildSubAVL(int[] nums, int start, int end){
if(start > end){
return null;
}
int index = (start + end)/2;
TreeNode root = new TreeNode();
root.val = nums[index];
root.left = buildSubAVL(nums, start, index-1);
root.right = buildSubAVL(nums, index + 1, end);
return root;
}
}
原来的判空条件是这样写的,结果超时,栈溢出了。
if(start == end){
return new TreeNode(nums[start]);
}
230.二叉搜索树中第K小的元素
递归法完全遍历
根据BST性质,对其中序遍历得到的就是树中元素值递增的排列,能直接得到其中第K小的元素。
class Solution {
private List<TreeNode> inorder = new ArrayList<>();
public int kthSmallest(TreeNode root, int k) {
inorderTraverse(root);
return inorder.get(k-1).val;
}
private void inorderTraverse(TreeNode root){
if(root == null)return;
inorderTraverse(root.left);
inorder.add(root);
inorderTraverse(root.right);
}
}
刚想在遍历到第K个元素的时候进行return,不行好像因为它还在递归的过程中,return之后还是在函数里面。
迭代法不完全遍历
有进阶要求:如果BST频繁变化,比如频繁的插入删除等,每次查找都要遍历效率不高
视频二叉树中序遍历迭代,抓住访问的顺序和要处理的顺序是否一致,
右孩子为空弹栈,到上一层,很像前面的一题,附上迭代中序遍历的代码,结合迭代的ppt理解一下吧
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
Deque<TreeNode> stk = new LinkedList<TreeNode>();
while (root != null || !stk.isEmpty()) {
while (root != null) {
stk.push(root);
root = root.left;
}
root = stk.pop();
res.add(root.val);
root = root.right;
}
return res;
}
}
那关于这一题也就是在弹栈的时候计数,也就是处理的时候记录是第几个处理的,本来想在递归中写的,好像写不出来?
class Solution {
public int kthSmallest(TreeNode root, int k) {
Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
--k;
if (k == 0) {
break;
}
root = root.right;
}
return root.val;
}
}