这是自己第一次面试,之前没有看过面经,没有刷过oj,结果就很在意料之中了,现将该题记录,以缅怀自己逝去的鹅场工作机会。
题目:
给定一颗二叉搜索树,请找出其中第k大的节点。例如,在下图中,第三大节点的值是4。
首先什么是二叉搜索树?
百度百科的定义:二叉搜索树它或者是一颗空树,或者是是具有以下性质的二叉树:若它的左子树不为空,则左子树上的所有节点的值均小于它的根节点的值,若他的右子树不为空,则他的右子树上所有节点的值均大于它的根节点的值,且它的左右子树也分别为二叉排序树。
是二叉排序树的话,一个很重要的性质就是中序遍历二叉排序树得到的是一个递增有序的数列
这个自己当初面试的时候脑子不知道咋的居然没想法到这个。
那么要找到二叉排序树中的第k大的节点,只需要对二叉树进行中序遍历,那么就可以找到二叉树中的第k大的节点。
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int x) {
val = x;
}
}
public class 二叉搜索树的第k大节点 {
private static int mK;
public static TreeNode kThNode(TreeNode root, int k) {
if (root == null || k == 0) {
return null;
}
mK = k;
return findKthNode(root);
}
/**
* 使用递归的方式进行求解
*
* @param root 根节点
* @return 第k大节点
*/
private static TreeNode findKthNode(TreeNode root) {
TreeNode target = null;
// 左子树不为空的时候递归寻找
if (root.left != null) {
target = findKthNode(root.left);
}
// 当没有找到目标的时候,我们需要对k-1
if (target == null) {
if (mK == 1) {
return root;
}
mK--;
}
// 没有找到目标并且右子树不为空的时候,递归地在右子树中寻找
if (target == null && root.right != null) {
target = findKthNode(root.right);
}
return target;
}
/**
* 使用非递归的方式进行求解
*
* @param root 根节点
* @param k k表示第k大元素
*/
public static void findKthNumber(TreeNode root, int k) {
TreeNode temp = root;
int result = 0;
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || temp != null) {
// 沿着左子树走到尽头
while (temp != null) {
stack.push(temp);
temp = temp.left;
}
// 左分支走到尽头,开始遍历右分支
if (!stack.isEmpty()) {
temp = stack.pop();
result++;
if (result == k) {
System.out.print(temp.val + " ");
return;
}
temp = temp.right;
}
}
}
public static void main(String[] args) {
TreeNode root=new TreeNode(5);
TreeNode node3=new TreeNode(3);
TreeNode node2=new TreeNode(2);
TreeNode node4=new TreeNode(4);
root.left=node3;
node3.left=node2;
node3.right=node4;
System.out.println(kThNode(root,3).val); //输出4
}
}
下来做了之后发现其实并不难