【剑指offer】20.二叉搜索树的第k个节点

总目录:

算法之旅导航目录

 

1.问题描述

给定一棵结点数为n 二叉搜索树,请找出其中的第 k 小的TreeNode结点值。
1.返回第k小的节点值即可
2.不能查找的情况,如二叉树为空,则返回-1,或者k大于n等等,也返回-1
3.保证n个节点的值不一样
数据范围: 0≤n≤10000≤k≤1000,树上每个结点的值满足0≤val≤1000
进阶:空间复杂度 O(n),时间复杂度 O(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的结点即可。

 

2.问题分析

  1递归,压栈拉来储值,因为是有序的搜索树,必须使用中序搜索

2粗暴迭代,逻辑较为复杂,但这种中序迭代方式值得学习,同样也必须是中序搜索


3.代码实例

递归

 1 /**
 2  * struct TreeNode {
 3  *  int val;
 4  *  struct TreeNode *left;
 5  *  struct TreeNode *right;
 6  *  TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 7  * };
 8  */
 9 class Solution {
10   public:
11     /**
12      * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
13      *
14      *
15      * @param proot TreeNode类
16      * @param k int整型
17      * @return int整型
18      */
19     stack<int> sp;
20     int searchRet = -1;
21     int recurve(TreeNode* root, int k) {
22         //中止条件
23         if (!root) {
24             return -1;
25         }
26 
27         //递归调用,中序搜索
28         searchRet = recurve(root->left, k);
29         if (searchRet >= 0) {
30             return searchRet;
31         }
32 
33         //本层逻辑
34         sp.push(root->val);
35         if (sp.size() == k) {
36             return sp.top();
37         }
38 
39         //递归调用
40         searchRet = recurve(root->right, k);
41         if (searchRet >= 0) {
42             return searchRet;
43         }
44 
45         return searchRet;
46     }
47 
48     int KthNode(TreeNode* proot, int k) {
49         if (k <= 0) {
50             return -1;
51         }
52         return recurve(proot, k);
53     }
54 };
View Code

 粗暴迭代

 1 class Solution {
 2 public:
 3     int KthNode(TreeNode* proot, int k) {
 4         if(proot == NULL)
 5             return -1;
 6         //记录遍历了多少个数
 7         int count = 0;  
 8         TreeNode* p = NULL;
 9         //用栈辅助建立中序
10         stack<TreeNode*> s;   
11         while(!s.empty() || proot != NULL){
12             while (proot != NULL) {
13                 s.push(proot);
14                 //中序遍历每棵子树从最左开始
15                 proot = proot->left;   
16             }
17             p = s.top();
18             s.pop();
19             count++;
20             //第k个直接返回
21             if(count == k)
22                 return p->val;
23             proot = p->right;
24         }
25         //没有找到
26         return -1;
27     }
28 };
View Code

 

posted @ 2022-11-12 14:57  啊原来是这样呀  阅读(14)  评论(0编辑  收藏  举报