剑指offer系列之六十一:二叉树搜索树的第k个节点

题目描述

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

因为二叉搜索树是排序的,所以如果需要找出第k个节点只需要进行中序遍历就可以得到第k节点。不过中序遍历的结果就是排序的,所以实质上就是插入排序。可以利用一个集合,在遍历的过程中利用插入排序的算法就能得到第k个节点。下面是这种实现思路的实现代码(已被牛客AC):

public class Solution {
    //采用非递归中序遍历的方式得到第k大的节点
    TreeNode KthNode(TreeNode pRoot, int k) {
        if(pRoot== null) return pRoot;
        //创建一个变量指向第k大的节点
        int p = 0;
        //创建一个栈用于保存遍历的顺序
        Stack<TreeNode> s = new Stack<TreeNode>();
        TreeNode curNode = pRoot;
        while(curNode != null || !s.isEmpty()){
            while(curNode != null){
                s.add(curNode);
                curNode = curNode.left;
            }
            if(!s.isEmpty()){
                curNode = s.pop();
                p++;
                if(p == k) return curNode;
                curNode = curNode.right;
            }
        }
        return null;
    }

}
时间: 2024-12-11 12:10:30

剑指offer系列之六十一:二叉树搜索树的第k个节点的相关文章

剑指offer系列之六十:序列化二叉树

题目描述 请实现两个函数,分别用来序列化和反序列化二叉树 首先得理解题目的意思,序列化就是返回一个带有#和逗号的字符串.反序列化就是根据带有#和逗号的字符串返回一棵二叉树.比如对于二叉树 1 / \ 2 3 /\ /\ 4 5 6 7 来讲,序列化的结果是1,2,#,#,3,4,#,7,#,#,5,#,#,.而反序列化的结果则是输出一棵二叉树. 下面是具体的实现代码(已被牛客AC): String Serialize(TreeNode root) { StringBuilder sb = new

剑指offer系列之五十一:正则表达式匹配

题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式.例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配 由于只涉及两种正则表达式的匹配,所以关键是需要分清除匹配的所有情况,对于模式串来讲,出现了'.'和'*

剑指offer系列之四十一:和为S的两个数字且乘积最小

题目描述 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输出描述: 对应每个测试案例,输出两个数,小的先输出. 有了上一题的基础,解决这题应该不难,思路与上一题差不多,不过这里只需要要求两个数字即可.所以可以设定两个指针,第一个指针指向数组的第一个元素,第二个指针指向最后一个元素,不断改变第一个指针的位置就可以确定和为S的两个数字.这里还有一个要求是这两个数字的乘积最小,实际上由于数组是递增排序的,所以第一个找到

剑指offer系列之三十一:把数组排成最小的数

题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 根据结果判断,所谓最小的数字实际上就是对数组中所有元素的一个组合.一种笨拙的方法是求出所有元素的全排列,然后对所有排列的值的大小进行排序,那么就可以得到最小的数了.求全排列的算法已经在之前的文章中提到.那么是不是还有其他思路呢?联想到Java库函数中有一个sort方法,是不是可以直接使用呢?(该sort方法的时

剑指offer系列之六十五:机器人的运动范围

题目描述 地上有一个m行和n列的方格.一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子. 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18.但是,它不能进入方格(35,38),因为3+5+3+8 = 19.请问该机器人能够达到多少个格子? 这题实际与上一题"矩阵中的路径"思路是相似的,都是需要创建一个状态数组对访问的格子进行标记,但是这里需要计算所有能够走的格子总数,实际

剑指offer系列之十一:数值的整数次方

题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 首先,我觉得这道题思路应该很简单,幂的情况无非是三种:正数.0和负数.当幂是0的时候,直接返回1:当幂是负数的时候,需要先把其转化为正数来处理,然后返回其倒数就可以了:当幂是正数的时候,按照正常的计算方法就可以.实际上这道题主要考察时代码的健壮性--就是对幂的情况的考虑是否周全.下面是实现的代码(已被牛客AC): package com.rhwayfun.offer; pub

剑指offer系列之六十三:滑动窗口的最大值

题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值.例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}: 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,

剑指offer系列之六十四:矩阵中的路径

题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子. 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子. 这实际上是回

剑指offer系列之六十二:数据流中的中位数

题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. 根据题目的意思,就是对数据流中的数据进行排序然后得到其中位数.要解决的关键问题是如何在读入数据的时候就对数据进行排序.实际上可以看成是插入排序算法的应用,可以维持一个List集合,保证每次读入数据集合中的数据都是排序的.基本思路是:从集合的第一个元素开始,依次比较与新读入的元素的大小关系,从而把新读入