530.二叉搜索树的最小绝对差
题目链接:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
求解思路:
注意这是一棵二叉搜索树,其中序遍历为一个有序数组,那么最小值必定出现在相邻两个数之间。
递归三部曲
- 确定递归函数的参数和返回值:参数为根节点,不需要返回值,结果用一个全局变量result记录
- 确定终止条件:遍历到空节点
- 确定单层递归的逻辑:用pre记录前一个节点,result不断取相邻数字差值的最小值
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
int result = INT_MAX;
TreeNode* pre = NULL;
// 中序遍历,因为二叉搜索树的中序遍历是一个有序数组
// 最小值一定出现在相邻的两个数之间
void traversal(TreeNode* cur){
if (cur == NULL) return;
traversal(cur->left);
if (pre != NULL)
result = min(result, cur->val - pre->val);
pre = cur; //记录前一个
traversal(cur->right);
}
public:
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
};
题目链接:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
求解思路:
中序遍历二叉搜索树。
遍历一边数组,如果一个数的频率count等于maxCount(最大频率),则把这个数加入结果集。
最大频率需要遍历的过程中实时更新,如果遇到频率更大就更新最大频率并将结果集清空。
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
int maxCount = 0; // 最大频率
int count = 0; // 统计频率
TreeNode* pre = NULL; // 前一个元素
vector<int> result;
void searchBST(TreeNode* cur){
if (cur == NULL) return;
searchBST(cur->left);
if (pre == NULL)
count = 1; // 第一个节点
else if (pre->val == cur->val)
count++; // 与前一个节点相同
else
count = 1; // 与前一个节点不同
pre = cur;
if (count == maxCount)
result.push_back(cur->val);
if (count > maxCount){
maxCount = count;
result.clear();
result.push_back(cur->val);
}
searchBST(cur->right);
return;
}
public:
vector<int> findMode(TreeNode* root) {
searchBST(root);
return result;
}
};
236. 二叉树的最近公共祖先
题目链接:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
求解思路:
后序遍历。
递归三部曲
- 确定递归函数返回值和参数:返回值为bool类型,参数为根节点以及目标值p、q的指针
- 确定终止条件:遇到空返回空;如果root == q,或者 root == p,说明找到 q或p ,将其返回
- 确定单层递归逻辑:用一个变量left、right接住返回值;如果left 和 right都不为空,说明此时root就是最近公共节点;如果left为空,right不为空,就返回right,说明目标节点是通过right返回的,反之亦然。
寻找的流程图
三点注意事项
-
求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
-
在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
-
要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。
代码:
/**
* 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == q || root == p || root == NULL) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if (left != NULL && right != NULL) return root;
if (left == NULL && right != NULL) return right;
else if (left != NULL && right == NULL) return left;
else // (left == NULL && right == NULL)
return NULL;
}
};