LeetCode: 剑指 Offer II 052. 展平二叉搜索树
描述:
给你一棵二叉搜索树,请 按中序遍历 将其重新排列为一棵递增顺序搜索树,使树中最左边的节点成为树的根节点,并且每个节点没有左子节点,只有一个右子节点。
class Solution {
// 让pre.next表示头节点
private TreeNode pre = new TreeNode();
// 让tmp来指向添加节点的操作
private TreeNode tmp = pre;
public TreeNode increasingBST(TreeNode root) {
if(root == null) return null;
increasingBST(root.left);
tmp.right = new TreeNode(root.val);
tmp = tmp.right;
increasingBST(root.right);
return pre.right;
}
}
LeetCode: 剑指 Offer II 053. 二叉搜索树中的中序后继
描述:
给定一棵二叉搜索树和其中的一个节点 p
,找到该节点在树中的中序后继。如果节点没有中序后继,请返回 null
。
节点 p
的后继是值比 p.val
大的节点中键值最小的节点,即按中序遍历的顺序节点 p
的下一个节点。
class Solution {
public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
TreeNode ans = null;
while(root != null) {
// root.val > p.val 就不需要取右子树找了, 右边只会更大
if(root.val > p.val){
// 每次都记录, 最终的ans就是最后需要的节点
ans = root;
root = root.left;
}else{
root = root.right;
}
}
return ans;
}
}
LeetCode: 剑指 Offer II 054. 所有大于等于节点的值之和
描述:
给定一个二叉搜索树,请将它的每个节点的值替换成树中大于或者等于该节点值的所有节点值之和。
提醒一下,二叉搜索树满足下列约束条件:
class Solution {
private int sum = 0;
public TreeNode convertBST(TreeNode root) {
if(root == null) return null;
convertBST(root.right);
// 修改该节点的值
root.val += sum;
sum = root.val;
convertBST(root.left);
return root;
}
}
LeetCode: 剑指 Offer II 055. 二叉搜索树迭代器
描述:
实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:
BSTIterator(TreeNode root)
初始化 BSTIterator
类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。boolean hasNext()
如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。int next()
将指针向右移动,然后返回指针处的数字。可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。
- 初始化的时候, 将节点以 中序遍历 的方法存入到list中
next()
的时候, 返回index++
节点的值index初始为0
hasNext()
的时候, 只要index!
就是 true
, 反之就是false
class BSTIterator {
private List<Integer> list = new ArrayList<>();
private int index = 0;
public BSTIterator(TreeNode root) {
inorderBST(root);
}
public TreeNode inorderBST(TreeNode root) {
if(root == null) return null;
inorderBST(root.left);
list.add(root.val);
inorderBST(root.right);
return root;
}
public int next() {
return list.get(index++);
}
public boolean hasNext() {
if(index < list.size()) {
return true;
}else{
return false;
}
}
}
LeetCode: 剑指 Offer II 056. 二叉搜索树中两个节点之和
描述:
给定一个二叉搜索树的 根节点 root 和一个整数 k , 请判断该二叉搜索树中是否存在两个节点它们的值之和等于 k 。假设二叉搜索树中节点的值均唯一。
- 这里使用的是 哈希表 思路
- 对于当前节点的值
root.val
我们判断k - root.val
是否存在哈希表中.
- 如果存在, 那么就有两个节点加起来的值为
k
- 如果不存在, 那么就将该节点的值加入 哈希表中
class Solution {
private Set<Integer> set = new HashSet<>();
public boolean findTarget(TreeNode root, int k) {
if(root == null) return false;
// 如果 k-root.val 的值 存在, 就返回true;
if(set.contains(k-root.val)) return true;
// 如果 不存在, 就添加到 哈希表上.
set.add(root.val);
return findTarget(root.left,k) || findTarget(root.right,k);
}
}
LeetCode: 剑指 Offer II 059. 数据流的第 K 大数值
描述:
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest
类:
KthLargest(int k, int[] nums)
使用整数 k
和整数流 nums
初始化对象。int add(int val)
将 val
插入数据流 nums
后,返回当前数据流中第 k
大的元素。
- 这里使用 优先级队列, 来进行添加.
- 初始化的时候, 初始一个优先级队列 大小为
k
的 小根堆, 然后将nums
数组添加到这个优先级队列中.- add操作的时候,
- 如果当前队列没满, 就直接入队, 如果满了,
- 判断当前队顶元素, 是否小于这个插入的值, 如果小于, 弹出栈顶元素, 然后入队这个值
class KthLargest {
private int k;
private PriorityQueue<Integer> pq;
public KthLargest(int k, int[] nums) {
this.k = k;
pq = new PriorityQueue<>(k,(o1,o2)->(o1-o2));
for(int num : nums) {
add(num);
}
}
public int add(int val) {
if(pq.size() < k) {
pq.offer(val);
}else{
if(val > pq.peek()) {
pq.poll();
pq.offer(val);
}
}
return pq.peek();
}
}