剑指 Offer 54. 二叉搜索树的第k大节点[简单][未做出]

题目

给定一棵二叉搜索树,请找出其中第k大的节点。
 限制:1 ≤ k ≤ 二叉搜索树元素个数
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

  1. 首先看一下二叉搜索树的定义

在二叉搜索树中:
1.若任意结点的左子树不空,则左子树上所有结点的值均不大于它的根结点的值。
2.若任意结点的右子树不空,则右子树上所有结点的值均不小于它的根结点的值。
3.任意结点的左、右子树也分别为二叉搜索树。

  1. 然后看一下二叉搜索树的中序遍历可以发现刚好是从小到大的顺序
  2. 发现过后一激动就开始写代码了,通过k的递减来找到目标树,没发现原来题目要求的是第k大节点
  3. 不过发现后也不难,直接翻过来的中序排序即可
  4. 难的主要是如何在递归过程中保存结果值和提前返回,最终没想到特别好的解法,直接看了网友题解,发现也是利用全局变量或者匿名函数,正好练习一下go的匿名函数了
  5. go的匿名函数也不难,主要是如果想要递归调用的话,得先声明函数签名再去定义
  6. 最后发现当年自己写的出入栈的迭代方法其实更好

代码

func kthLargest(root *TreeNode, k int) int {
    // 先序遍历就是按顺序
    var res int
    var reverseInOrder func(n *TreeNode)
    reverseInOrder = func(n *TreeNode){
        if n == nil {
            return 
        }
        reverseInOrder(n.Right) 
        k--
        if k == 0 {
            res = n.Val
        }
        reverseInOrder(n.Left) 
    }
    reverseInOrder(root)

    return res
}

旧blog

题目描述

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/

【未做出】
没什么特别的,就是复习一下迭代中序遍历吧
尴尬,还是没做出,主要是就是卡在右子树的进栈那里了,通过右子树和进出栈配合从而保证左子树不会重复入栈

class Solution {
public:
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        if(k<=0 || pRoot == NULL)
            return NULL;
        stack<TreeNode*> nodeStack;
        TreeNode* curNode;
        curNode = pRoot;
        while(curNode||nodeStack.size())
        {
            while(curNode){
                nodeStack.push(curNode);
                curNode = curNode->left;
            }
            curNode = nodeStack.top();
            nodeStack.pop();
            --k;
            if(k==0)
                return curNode;
            curNode = curNode->right;
        }
        return NULL;
    }
};

书本题解:
如果按照中序遍历的顺序遍历一棵二叉搜索树,则遍历序列的数值是递增排序的。

const BinaryTreeNode* KthNode(const BinaryTreeNode* pRoot, unsigned int k)
{
    if(pRoot == nullptr || k == 0)
        return nullptr;

    return KthNodeCore(pRoot, k);
}

const BinaryTreeNode* KthNodeCore(const BinaryTreeNode* pRoot, unsigned int& k)
{
    const BinaryTreeNode* target = nullptr;

    if(pRoot->m_pLeft != nullptr)
        target = KthNodeCore(pRoot->m_pLeft, k);

    if(target == nullptr)
    {
        if(k == 1)
            target = pRoot;

        k--;
    }

    if(target == nullptr && pRoot->m_pRight != nullptr)
        target = KthNodeCore(pRoot->m_pRight, k);

    return target;
}
posted @ 2021-11-25 23:57  lixin_longway  阅读(14)  评论(0)    收藏  举报