题目描述
给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
1.中序遍历ArrayList添加,按照索引取出
思路:由于二叉搜索树的中序遍历结果是有序的序列。因此将此序列取出放入ArrayList中,然后取出第k个元素即可得到第k大的节点。
import java.util.ArrayList;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
TreeNode KthNode(TreeNode pRoot, int k){
//不满足条件直接返回空节点
if(k<=0||pRoot==null) return null;
ArrayList<TreeNode> arr=new ArrayList<TreeNode>();
TreeNode test=new TreeNode(-1);
//由于第k大是节点的索引是k-1因此,首先将test放入ArrayList中,然后直接去k索引处的节点
if(arr.size()==0) arr.add(test);
//中序遍历
Inorder(pRoot,arr);
//不满足条件直接返回,避免递归层数
if(k>arr.size()-1) return null;
return arr.get(k);
}
public void Inorder (TreeNode pRoot,ArrayList<TreeNode> arr){
if(pRoot==null) return;
Inorder(pRoot.left,arr);
arr.add(pRoot);
Inorder(pRoot.right,arr);
}
}
直接返回k-1处的节点,和上面雷同:
public class Solution {
TreeNode KthNode(TreeNode pRoot, int k){
//不满足条件直接返回空节点
if(k<=0||pRoot==null) return null;
ArrayList<TreeNode> arr=new ArrayList<TreeNode>();
Inorder(pRoot,arr);
if(k>arr.size()) return null;
return arr.get(k-1);
}
public void Inorder (TreeNode pRoot,ArrayList<TreeNode> arr){
if(pRoot==null) return;
Inorder(pRoot.left,arr);
arr.add(pRoot);
Inorder(pRoot.right,arr);
}
}
2.递归遍历,根据当前索引返回
思路:递归遍历,当index值等于k时,返回pRoot节点。值得注意的是递归终止条件是:当node节点非空时候才返回node节点,否则得不到k处的值。
public class Solution {
int index=0;
TreeNode KthNode(TreeNode pRoot, int k)
{
if(pRoot!=null){
TreeNode node=KthNode(pRoot.left,k);
if(node!=null) return node;
index++;
if(index==k) return pRoot;
node=KthNode(pRoot.right,k);
if(node!=null) return node;
}
return null;
}
}