力扣高频|算法面试题汇总(一):开始之前
力扣高频|算法面试题汇总(二):字符串
力扣高频|算法面试题汇总(三):数组
力扣高频|算法面试题汇总(四):堆、栈与队列
力扣高频|算法面试题汇总(五):链表
力扣高频|算法面试题汇总(六):哈希与映射
力扣高频|算法面试题汇总(七):树
力扣高频|算法面试题汇总(八):排序与检索
力扣高频|算法面试题汇总(九):动态规划
力扣高频|算法面试题汇总(十):图论
力扣高频|算法面试题汇总(十一):数学&位运算
力扣高频|算法面试题汇总(七):树
力扣链接
目录:
- 1.二叉搜索树中第K小的元素
- 2.二叉树的最近公共祖先
- 3.二叉树的序列化与反序列化
- 4.天际线问题
1.二叉搜索树中第K小的元素
给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/
1 4
2
输出: 1
进阶:
如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化 kthSmallest 函数?
思路:
这题剑指offer中做过,详见:剑指offer|解析和答案(C++/Python) (五)上:二叉搜索树的第k个节点
就是通过中序遍历查找。
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
// 中序遍历获得二叉搜索树的第k个节点
TreeNode* pNode = kthSmallestCore(root, k);
return pNode->val;
}
TreeNode* kthSmallestCore(TreeNode* pRoot, int& k){
TreeNode* target = NULL;
if(pRoot->left != NULL)//遍历左子树
target = kthSmallestCore(pRoot->left, k);
if(target == NULL){
if(k == 1)//表示已经到第k小的节点了
target = pRoot;
k--;
}
//target = NULL 表示没有找到
//开始遍历右子树
if(target == NULL && pRoot->right != NULL){
target = kthSmallestCore(pRoot->right, k);
}
return target;
}
};
官方的极简写法:
class Solution:
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
def inorder(r):
return inorder(r.left) + [r.val] + inorder(r.right) if r else []
return inorder(root)[k - 1]
思路2:
参考官方思路,进行迭代加速。
时间复杂度:O(H+k),其中 HH 指的是树的高度,由于我们开始遍历之前,要先向下达到叶,当树是一个平衡树时:复杂度为 O(logN+k)。当树是一个不平衡树时:复杂度为 O(N+k),此时所有的节点都在左子树。
空间复杂度:O(H+k)。当树是一个平衡树时:O(logN+k)。当树是一个非平衡树时:O(N+k)。
C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
stack<TreeNode*> s;
while(1){
while(root){
s.push(root);
root = root->left;
}
root = s.top();
s.pop();
--k;
if(k == 0)
return root->val;
root = root->right;
}
}
};
Python:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def kthSmallest(self, root: TreeNode, k: int) -> int:
stack = []
while True:
while root:
stack.append(root)
root = root.left
root = stack[-1]
stack.pop()
k -= 1
if not k: