题目链接

牛客网
LeetCode

题目描述

  1. 给定一棵二叉搜索树,请找出其中的第k小的结点。
  2. 给定一棵二叉搜索树,请找出其中第k大的节点。

    示例1

    1. 输入:
    2. {5,3,7,2,4,6,8},3
    3. 返回:
    4. {4}
    5. 按结点数值大小顺序第三小结点的值为4

    示例2

    输入: root = [3,1,4,null,2], k = 1
    3
    / \
    1 4
    \
    2
    输出: 4

    解题思路

    题目一

    利用二叉查找树中序遍历有序的特点。
    先查找左子树,然后判断当前根结点为第几个,然后查找右子树。
  1. /*
  2. struct TreeNode {
  3. int val;
  4. struct TreeNode *left;
  5. struct TreeNode *right;
  6. TreeNode(int x) :
  7. val(x), left(NULL), right(NULL) {
  8. }
  9. };
  10. */
  11. class Solution {
  12. public:
  13. TreeNode* KthNode(TreeNode* pRoot, int k)
  14. {
  15. if(pRoot==nullptr) return nullptr;
  16. inOrder(pRoot,k);
  17. return ret;
  18. }
  19. private:
  20. TreeNode* ret=NULL;
  21. int cut = 0;
  22. void inOrder(TreeNode* root, int k){
  23. if(root==nullptr||cut>=k)
  24. return;
  25. inOrder(root->left,k); // 查找左子树
  26. cut++; // 访问根结点,当前被访问结点个数加一
  27. if(cut==k){
  28. ret = root;
  29. return;
  30. }
  31. inOrder(root->right,k); // 查找右子树
  32. }
  33. };

题目二

二叉搜索树的 中序遍历倒序 递减序列
因此,求 “二叉搜索树第 k 大的节点” 可转化为求 “此树的中序遍历倒序的第 k 个节点”。
中序遍历的倒序 为 “右、根、左” 顺序,递归法代码如下:

  1. # 打印中序遍历倒序
  2. def dfs(root):
  3. if not root: return
  4. dfs(root.right) # 右
  5. print(root.val) # 根
  6. dfs(root.left) # 左
  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. int kthLargest(TreeNode* root, int k) {
  13. if(root==nullptr||k=0)
  14. return 0;
  15. inOrder(root,k);
  16. return ret;
  17. }
  18. private:
  19. int cut=0;
  20. int ret=0;
  21. void inOrder(TreeNode* root,int k){
  22. if(root==nullptr)
  23. return;
  24. inOrder(root->right,k);
  25. cut++;
  26. if(cut==k){
  27. ret = root->val;
  28. return;
  29. }
  30. inOrder(root->left,k);
  31. }
  32. };