1.二叉搜索树中第k小的元素
【题目】
给定一个二叉搜索树的根节点 root
,和一个整数 k
,请你设计一个算法查找其中第 k
个最小元素(从 1 开始计数)。
【分析】
递归实现,根据二叉搜索树的性质,中序遍历二叉搜索树,即先查找左子树,然后将当前节点放入数组num中,然后先查找右子树,不断重复上述过程,直至遍历到叶子节点结束,最终就得到了有序的数组nums,答案即为num[k−1]。
【代码】
C++:时间O(n),空间O(n)
class Solution {
public:
vector<int> num;
int kthSmallest(TreeNode* root, int k) {
dfs(root);
return num[k - 1];
}
void dfs(TreeNode *node) {
if (node->left != NULL)
dfs(node->left);
num.push_back(node->val);
if (node->right != NULL)
dfs(node->right);
}
};
C
#define MAX_NUM 10000
void dfs(struct TreeNode *root, int *arr, int *len)
{
if (root == NULL) {
return;
}
/* 中序遍历该二叉树 */
dfs(root->left, arr, len); // 先遍历左子树
arr[(*len)++] = root->val; // 再遍历父节点
dfs(root->right, arr, len); // 最后遍历右子树
}
int kthSmallest(struct TreeNode *root, int k)
{
int ret[MAX_NUM] = {0};
int len = 0;
dfs(root, ret, &len);
return ret[k - 1]; // 因为下标从1开始,因此第k的元素的下标是k-1
}
2.监控二叉树
【题目】
【分析】参考leetcode-master/0968.监控二叉树.md at master · youngyangyang04/leetcode-master · GitHub
【代码】C
/*
**函数后序遍历二叉树。判断一个结点状态时,根据其左右孩子结点的状态进行判断
**状态:0为没有被摄像头覆盖到。1为此结点处应设置摄像头。2为此结点已被摄像头覆盖
*/
int traversal(struct TreeNode* node, int* ans) {
//递归结束条件:传入结点为NULL,假设此结点能被摄像头覆盖。这样方便与对叶子结点的判断,将叶子结点设为0
if(!node)//遇到空节点
return 2;
//后序遍历二叉树,记录左右孩子的状态。根据左右孩子状态更新结点自身状态
int left = traversal(node->left, ans);
int right = traversal(node->right, ans);
//若左右孩子都可以被摄像头覆盖,将父亲结点状态设为0
if(left == 2 && right == 2) {
return 0;
}
//若左右孩子有一个结点状态为没有被覆盖(0),则将父亲结点状态设置为摄像头
if(left == 0 || right == 0) {
(*ans)++;
return 1;
}
//若左右孩子有一个为摄像头,证明父亲结点可以被覆盖。将父亲结点状态变为2
if(left == 1 || right == 1)
return 2;
//逻辑不会走到-1,语句不会执行
return -1;
}
int minCameraCover(struct TreeNode* root){
int ans = 0;
//在对整个二叉树遍历后。头结点可能未被覆盖,这时候如果函数返回值为0,证明头结点未被覆盖。说明头结点也需要添置摄像头,ans++
if(traversal(root, &ans) == 0)
ans++;
return ans;
}