题目:二叉搜索树的第k个结点
给定一棵二叉搜索树,按节点值从小到大排列,找出其中的第k(k≥1)个结点。
主要思路:使用中序遍历,每遍历一个节点时,判断k的值,若k等于1,则当前遍历到的节点就是所求节点,否则使k减1。
关键点:中序遍历
时间复杂度:O(n)
public class KthNodeOfTree{
private static TreeNode result;
private static int runK;
public static void main(String[] args){
// 10
// / \
// 6 14
// /\ /\
// 4 8 12 16
TreeNode root = TreeNode.generateBinaryTree();
System.out.println(findKthNode(root, 1).val); //4
System.out.println(findKthNode(root, 3).val); //8
System.out.println(findKthNode(root, 5).val); //12
//System.out.println(findKthNodeByLoop(root, 5).val); //12
}
private static TreeNode findKthNode(TreeNode root, int k) {
if (root == null || k == 0) return null;
result = null;
runK = k;
findKthNode(root);
return result;
}
//递归
private static void findKthNode(TreeNode root){
if (root == null || result != null) return;
//中序遍历,先遍历左节点
findKthNode(root.left);
if (result == null) {
if (runK == 1){
result = root;
return;
}
runK--;
}
//遍历右节点
findKthNode(root.right);
}
//循环
private static TreeNode findKthNodeByLoop(TreeNode root, int k){
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
if (!stack.isEmpty()){
cur = stack.pop();
if (k == 1){
return cur;
}
k--;
cur = cur.right;
}
}
return null;
}
}
我的版本:
int sum = 0;
TreeNode ret = null;
TreeNode KthNode(TreeNode pRoot, int k){
if(pRoot == null)
return ret;
if(pRoot.left != null)
KthNode(pRoot.left, k);
sum++;
if(sum == k) {
ret = pRoot;
}
if(pRoot.right != null)
KthNode(pRoot.right, k);
return ret;
}
难理解版递归:
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;
}
}