问题
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
例子
思路
二叉搜索树中序遍历得到从小到大的顺序
-
方法1
中序遍历+list保存遍历的结点
-
方法2
使用全部变量【res和n:因为int型作为参数是值传递,无法保存每次操作后的值】,保存第k个值,和现在数到第几个数
代码
//方法1
public int kthSmallest(TreeNode root, int k) {
List<Integer> list = new ArrayList<>();
midOrder(root,list);
return list.get(k-1);
}
public void midOrder(TreeNode root, List<Integer> list) {
if(root==null) return;
if(root.left!=null) midOrder(root.left,list);
list.add(root.val);
if(root.right!=null) midOrder(root.right,list);
return;
}
//方法2
class Solution {
private int res=0;
private int n=0;
public int kthSmallest(TreeNode root, int k) {
midOrder(root,k);
return res;
}
public void midOrder(TreeNode root, int k) {
if(root==null || n>k) return;
if(root.left!=null) midOrder(root.left,k);
n++;
if(n==k) res=root.val;
if(root.right!=null) midOrder(root.right,k);
return;
}
}
面试题54. 二叉搜索树的第k大节点
思路
//同二叉搜索树的第k小,不同的是,前者使用中序遍历,而它使用倒中序遍历,右根左
//方法1
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private int n=0;
private int res=0;
public int kthLargest(TreeNode root, int k) {
//若不是二叉搜索树,是普通的二叉树,可用小顶堆
// PriorityQueue<Integer> q = new PriorityQueue<>()
// preOrder(root,k,q);
// return q.peek();
//二叉搜索树 中序遍历得到 有序
// List<Integer> list = new ArrayList<>();
// midOrder(root,k,list);
// return list.get(list.size()-k);
//同二叉搜索树的第k小,不同的是,前者使用中序遍历,而它使用倒中序遍历,右根左
fanMidOrder(root,k);
return res;
}
public void fanMidOrder(TreeNode root, int k) {
if(root==null || n>k) return;
if(root.right!=null) fanMidOrder(root.right, k);
n++;
if(n==k) res=root.val;
if(root.left!=null) fanMidOrder(root.left,k);
return;
}
public void midOrder(TreeNode root, int k, List<Integer> list) {
if(root==null) return ;
if(root.left!=null) midOrder(root.left,k,list);
list.add(root.val);
if(root.right!=null) midOrder(root.right,k,list);
}
public void preOrder(TreeNode root, int k, PriorityQueue<Integer> q) {
if(root==null) return;
if(q.size()<k) q.add(root.val);
else {//q.size()==k
if(root.val>q.peek()) {
q.poll();
q.offer(root.val);
}
}
if(root.left!=null) preOrder(root.left,k,q);
if(root.right!=null) preOrder(root.right,k,q);
}
}
//方法2