首页 > 试题广场 >

二叉搜索树的第k个节点

[编程题]二叉搜索树的第k个节点
  • 热度指数:54923 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一棵点数为n 二叉搜索树,请找出其中的第 k 小的TreeNode结点值。
1.返回第k小的节点值即可
2.不能查找的情况,如二叉树为空,则返回-1,或者k大于n等等,也返回-1
3.保证n个节点的值不一样


数据范围: ,树上每个结点的值满足
进阶:空间复杂度 ,时间复杂度


如输入{5,3,7,2,4,6,8},3时,二叉树{5,3,7,2,4,6,8}如下图所示:

该二叉树所有节点按结点值升序排列后可得[2,3,4,5,6,7,8],所以第3个结点的结点值为4,故返回对应结点值为4的结点即可。

示例1

输入

{5,3,7,2,4,6,8},3

输出

4
示例2

输入

{},1

输出

-1

备注:
当树是空

说明:本题目包含复杂数据结构TreeNode,点此查看相关信息
int cnt;
public int KthNode (TreeNode proot, int k) {
    // write code here
    cnt=k;
    return dfs(proot);

}

public int dfs(TreeNode root){
    if(root==null){
        return -1;
    }
    int left = dfs(root.left);
    if(--cnt==0){
        return root.val;
    }
    int right=dfs(root.right);
    return Math.max(left ,right);
}

编辑于 2024-03-09 15:56:55 回复(0)

public int KthNode (TreeNode proot, int k) {

    // write code here

    if (proot == null) return -1;

    //int n = GetNodeNum(proot);

    ArrayListInteger> tree = new ArrayList();

    tree = inorderTraversalToList(proot);

    if (tree.size() 1) return -1;

    return tree.get(k - 1);

}

public static ArrayListInteger> inorderTraversalToList(TreeNode root) {

    ArrayListInteger> result = new ArrayList();

    inorderTraversal(root, result);

    return result;

}

private static void inorderTraversal(TreeNode root, ArrayListInteger> result) {

    if (root == null) {

        return;

    }

    // 中序遍历左子树

    inorderTraversal(root.left, result);

    // 处理当前节点

    result.add(root.val);

    // 中序遍历右子树

    inorderTraversal(root.right, result);

}
编辑于 2024-02-26 14:42:32 回复(0)
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param proot TreeNode类
     * @param k int整型
     * @return int整型
     */
    ArrayList<Integer> list;
    int sum;
    public int KthNode (TreeNode proot, int k) {
        // write code here
        if (proot == null || k == 0 || count(proot) < k) {
            return -1;
        }
        list = new ArrayList<>();
        dfs(proot, list);
        Collections.sort(list);
        return list.get(k - 1);
    }
    private void dfs(TreeNode proot, ArrayList<Integer> list) {
        if (proot == null) {
            return;
        }
        list.add(proot.val);
        dfs(proot.left, list);
        dfs(proot.right, list);
    }
    private int count(TreeNode proot) {
        if (proot == null) {
            return 0;
        }
        sum++;
        count(proot.left);
        count(proot.right);
        return sum;
    }

}
发表于 2023-03-31 11:24:48 回复(0)
public class Solution {
    public int KthNode (TreeNode proot, int k) {
        if (proot == null || k == 0) return -1;
        ArrayList<Integer> list = new ArrayList<>();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(proot);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            list.add(node.val);
            if (node.left != null) {
                queue.add(node.left);
            }
            if (node.right != null) {
                queue.add(node.right);
            }
        }
        Collections.sort(list);
        if(k > list.size()) return -1;
        return list.get(k - 1);
    }
}

发表于 2023-03-08 17:06:22 回复(0)
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param proot TreeNode类 
     * @param k int整型 
     * @return int整型
     */
     ArrayList<TreeNodelist = new ArrayList<>();
    public int KthNode (TreeNode prootint k) {
        if(proot==null || k==0)return-1;
        // write code here
        Bianli(proot);
        return list.size()>=k ? list.get(k-1).val : -1;
        
    }
    public void Bianli(TreeNode proot){
        if(proot==null)return;
        Bianli(proot.left);
        list.add(proot);
        Bianli(proot.right);
    } 
}
发表于 2022-11-12 15:35:45 回复(0)
public class Solution {
    // res -- 保存返回值,count -- 统计次数(第几小)
    int res = -1, count = 0;
    public int KthNode (TreeNode proot, int k) {
        if (proot == null) return res;
        inorder(proot, k);
        return res;
    }

    public void inorder(TreeNode proot, int k) {
        // 当遍历到节点为空或者超过k时,返回
        if (proot == null || count > k) return;
        inorder(proot.left, k);
        // 判断是否是需要的第k小
        if (++count == k) res = proot.val;
        inorder(proot.right, k);
    }
}
发表于 2022-08-17 20:01:15 回复(1)
1. 方法一:迭代法
2. 方法二:中序遍历
    // 方法一:迭代法
    public int KthNode1 (TreeNode proot, int k) {
        // write code here
        if(proot == null || k == 0) return -1;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = proot;
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            if(!stack.isEmpty()){
                cur = stack.pop();
                if(--k == 0){
                    return cur.val;
                }
            }
            cur = cur.right;
        }
        return -1;
    }
    // 方法二:中序遍历
    List<Integer> list = new ArrayList<>();
    public int KthNode (TreeNode proot, int k) {
        // write code here
        if(proot == null || k == 0) return -1;
        inOrder(proot);
        return k <= list.size() ? list.get(k-1) : -1;
    }
    private void inOrder(TreeNode proot){
        if(proot == null) return;

        inOrder(proot.left);
        list.add(proot.val);
        inOrder(proot.right);
    }



发表于 2022-08-01 10:38:10 回复(0)
import java.util.*;

public class Solution {

    public int KthNode (TreeNode proot, int k) {
        // write code here
        if(proot == null) {
            return -1;
        }
        ArrayList<Integer> list = sortTree(proot.left);
        if(list.size() == k - 1) {
            list.add(proot.val);
        }else if(list.size() < k - 1) {
            list.add(proot.val);
            list.addAll(sortTree(proot.right));
        }
        if(k <= 0 || k > list.size()) {
            return -1;
        }
        return list.get(k - 1);
    }
    
    public ArrayList<Integer> sortTree(TreeNode proot) {
        ArrayList<Integer> temp = new ArrayList<Integer>();
        if(proot == null) {
            return temp;
        }
        temp.addAll(sortTree(proot.left));
        temp.add(proot.val);
        temp.addAll(sortTree(proot.right));
        return temp;
    }
}

发表于 2022-07-31 09:37:33 回复(0)
import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param proot TreeNode类
     * @param k int整型
     * @return int整型
     */
    //空间o
,时间 <= o(n)
    //定义两个属性记录中序遍历的值
    int res = -1;
    int count;
    public int KthNode (TreeNode proot, int k) {
        // write code here
        if(proot==null) return -1;
        count = k;
        dfs(proot);
        return res;
    }
    //中序遍历,是搜索树从小到大的值遍历
    void dfs(TreeNode proot){
        //当res不等于-1时表示已经找到第k小的值了,直接返回,减枝
        if(res!=-1||proot==null) return;
        
        dfs(proot.left);
        //判断当前节点是否为第k小的节点
        if(--count==0){
            res = proot.val;
            return;
        }
        dfs(proot.right);
    }
}
发表于 2022-07-13 11:25:58 回复(0)
就利用一个性质:二叉搜索树的中序遍历的结果是从小到大升序排列的,然后取出来
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param proot TreeNode类 
     * @param k int整型 
     * @return int整型
     */
    List<Integer> list = new ArrayList<>();
    public int KthNode (TreeNode proot, int k) {
        // write code here
        //二叉搜索树中序遍历就是升序排列的
        if(proot == null) return -1;
        recursion(proot);
        if(list.size() < k) return -1;
        int res = -1;
        int index = 0;
        while(k > 0){
            res = list.get(index);
            k --;
            index ++;
        }
        return res ;
    }
    private void recursion(TreeNode root){
        if(root == null) return ;
        recursion(root.left);
        list.add(root.val);
        recursion(root.right);
    }
}


发表于 2022-05-22 17:22:24 回复(0)
public class Solution {
    private int num = 0;
    
    public int KthNode (TreeNode proot, int k) {
        if (proot == null) {
            return -1;
        }
        this.num = k;
        int result = KthNode(proot.left, k);
        if (result != -1) {
            return result;
        }
        if (--this.num == 0) {
            return proot.val;
        }
        return this.KthNode(proot.right, this.num);
    }
}

发表于 2022-05-10 14:19:47 回复(0)
//其实就是找到前序遍历的第k位元素。
 
import java.util.*;
 
public class Solution {
    int result = -1;
    int rank=0;
    public int KthNode (TreeNode proot, int k) {
        // write code here
        if(proot == null){
            return -1;
        }
        reverse(proot,k);
        return result;
         
    }
     
    public void reverse(TreeNode proot,int k) {
        if(proot == null){
            return;
        }
        reverse(proot.left,k);
        rank++;
        if(rank==k){
            result = proot.val;
            return;
        }
        reverse(proot.right,k);        
    }  
}

发表于 2022-05-08 21:58:28 回复(0)
public int KthNode (TreeNode proot, int k) {
        // write code here
        int[] ans = f(proot, k);
        if (ans[0] == 1)
            return ans[1];
        return -1;
    }
 
    public int[] f(TreeNode proot, int k) {
        if (proot == null)
            return new int[]{0,0,0};
        int[] left = f(proot.left, k);
        if (left[0] == 1)
            return left;
        if (left[2] == k-1)
            return new int[]{1,proot.val,0};
        int[] right = f(proot.right, k - left[2] - 1);
        if (right[0] == 1)
            return right;
        return new int[]{0,0,left[2]+1+right[2]};
    }

发表于 2022-05-01 18:56:02 回复(0)