目录:
给你一个二叉搜索树的根节点 root
,返回 树中任意两不同节点值之间的最小差值 。
差值是一个正数,其数值等于两值之差的绝对值。
示例 1:
!https://assets.leetcode.com/uploads/2021/02/05/bst1.jpg
输入:root = [4,2,6,1,3]
输出:1
思考:因为是二叉搜索树,所以任意两个不同节点最小差值只会出现在相邻节点。迭代法和递归方法。
递归方法:
class Solution {
public:
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);
}
int getMinimumDifference(TreeNode* root) {
traversal(root);
return result;
}
};
迭代法
class Solution {
public:
int getMinimumDifference(TreeNode* root) {
int result = INT_MAX;
TreeNode* pre = NULL;
TreeNode* cur = root;
stack<TreeNode*> st;
while(cur != NULL || !st.empty()) {
if (cur != NULL) {
st.push(cur);
cur = cur->left;
} else {
cur = st.top();
st.pop();
if (pre != NULL) {
result = min(result, cur->val - pre->val);
}
pre = cur;
cur = cur->right;
}
}
return result;
}
};
给你一个含重复值的二叉搜索树(BST)的根节点 root
,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。
如果树中有不止一个众数,可以按 任意顺序 返回。
假定 BST 满足如下定义:
示例 1:
!https://assets.leetcode.com/uploads/2021/03/11/mode-tree.jpg
输入:root = [1,null,2,2]
输出:[2]
思考:暴力方法:用一个map记录所有数字的出现次数,再找出众数。
其他方法,二叉搜索树在遍历的过程中,对于同一个数字总是一直持续的。所以,可以用一个count来记录重复数字出现的次数。然后返回的vector数组中,如果遇到的次数比之前的都大,则清空并存入最大的。如果一样大,则继续存入。(第一个节点没考虑到,maxCount更新没考虑到)
class Solution {
private:
int maxCount = 0;
int count = 0;
vector<int> result;
TreeNode* pre = NULL;
void searchBST(TreeNode* cur) {
if (cur == NULL) return;
searchBST(cur->left);
if (pre == NULL) count = 1;
if (pre != NULL && cur->val == pre->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) {
result.clear();
searchBST(root);
return result;
}
};
一般二叉树的统计方法:用unordered_map来统计:
class Solution {
private:
void searchBST(TreeNode* cur, unordered_map<int, int>& map) {
if (cur == NULL) return;
map[cur->val]++;
searchBST(cur->left, map);
searchBST(cur->right, map);
return;
}
bool static cmp(const pair<int, int>& a, const pair<int, int>& b) {
return a.second > b.second;
}
public:
vector<int> findMode(TreeNode* root) {
unordered_map<int, int> map;
vector<int> result;
if (root == NULL) return result;
searchBST(root, map);
vector<pair<int, int>> vec(map.begin(), map.end());
sort(vec.begin(), vec.end(), cmp);
result.push_back(vec[0].first);
for (int i = 1; i < vec.size(); i++) {
if (vec[i].second == vec[0].second) result.push_back(vec[i].first);
else break;
}
return result;
}
};
迭代遍历的逻辑一样,只是用的是st来进行遍历。
class Solution {
private:
public:
vector<int> findMode(TreeNode* root) {
int maxCount = 0;
int count = 0;
TreeNode* pre = NULL;
TreeNode* cur = root;
vector<int> result;
stack<TreeNode*> st;
while(cur != NULL || !st.empty()) {
if (cur != NULL) {
st.push(cur);
cur = cur->left;
} else {
cur = st.top();
st.pop();
if (pre == NULL) count = 1;
if (pre != NULL && cur->val == pre->val) count++;
else count = 1;
if (count == maxCount) result.push_back(cur->val);
if (count > maxCount) {
maxCount = count;
result.clear();
result.push_back(cur->val);
}
pre = cur;
cur = cur->right;
}
}
return result;
}
};
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。
例 1:
!https://assets.leetcode.com/uploads/2018/12/14/binarytree.png
输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
思考:如果找到一个节点,发现左子树出现结点p,右子树出现节点q,或者 左子树出现结点q,右子树出现节点p,那么该节点就是节点p和q的最近公共祖先。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == NULL || root == p || root == q) 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;
if (left != NULL && right == NULL) return left;
else {
return NULL;
}
}
};
在递归函数有返回值的情况下:如果要搜索一条边,递归函数返回值不为空的时候,立刻返回,如果搜索整个树,直接用一个变量left、right接住返回值,这个left、right后序还有逻辑处理的需要,也就是后序遍历中处理中间节点的逻辑(也是回溯)。
归纳:
二叉搜索树的特性,经常和双指针法一起使用。
迭代法和递归法的一般写法。