1、题目描述
给定一颗二叉搜索树,请找出其中的第k小的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。
2、我的解答
利用二叉搜索树的中序遍历结果为单调递增性质,对该二叉搜索树进行中序遍历,并将中序遍历结果存入数组中,在主函数中调用其中序遍历函数,并返回数组中的第k-1个结点。
源码如下:
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)
{
ArrayList<TreeNode> array1=new ArrayList<TreeNode>();
if(pRoot==null){
return null;
}
array1=midOrder(pRoot);
if(k>array.size() || k<=0){
return null;
}
return array1.get(k-1);//一定要注意是k-1
}
ArrayList<TreeNode> array=new ArrayList<TreeNode>();
ArrayList<TreeNode> midOrder(TreeNode pRoot){//中序遍历
if(pRoot.left!=null){
midOrder(pRoot.left);
}
//array.add(midOrder(pRoot.left));
array.add(pRoot);
//array.add(midOrder(pRoot.right));
if(pRoot.right!=null){
midOrder(pRoot.right);
}
return array;
}
}
另一种写法:
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)
{
ArrayList<TreeNode> array1=new ArrayList<TreeNode>();
if(pRoot==null){
return null;
}
array1=midOrder(pRoot);
if(k>array.size() || k<=0){
return null;
}
return array1.get(k-1);//一定要注意为k-1
}
ArrayList<TreeNode> array=new ArrayList<TreeNode>();
ArrayList<TreeNode> midOrder(TreeNode pRoot){//中序遍历
if(pRoot==null){
return array;
}
midOrder(pRoot.left);
array.add(pRoot);
midOrder(pRoot.right);
return array;
}
}
3、不遍历完整个数组的解法(请记住,背过!!!)
题目的本质考察的是中序遍历,只是我们要维护一个记录遍历到第几个节点的变量。
在这里我们用index变量进行维护,当index==k时我们就返回该节点。
下面是非递归代码的实现形式:
中序遍历,非递归,利用栈!
import java.util.Stack;
/*
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(pRoot==null || k<=0){
return null;
}
Stack<TreeNode> stack=new Stack<TreeNode>();
int index=0;
while(pRoot!=null || !stack.isEmpty()){//背过中序遍历非递归算法!!!
while(pRoot!=null){//走到最左端
stack.push(pRoot);
pRoot=pRoot.left;
}
if(!stack.isEmpty()){//开始出栈
pRoot=stack.pop();
index++;
if(index==k){
return pRoot;
}else{
pRoot=pRoot.right;
}
}
}
return null;
}
}