530. 二叉搜索树的最小绝对差
如果是一颗普通树,则使用暴力求解法:遍历树并保存树种每个节点的值,排序后找差值最小的元素。
本题给的是一颗二叉搜索树(BST),所以其中序遍历就是一个单调递增(不减)序列,而差值最小的两个节点一定是中序遍历中相邻的两个元素。因此,使用中序遍历找相邻两元素之间的最小差值。
本题的思路与98. 验证二叉搜索树的思路很像。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
递归
// c++
/**
* 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 {
public:
void Order(TreeNode* root, int& min_diff, TreeNode* &pre){
if(!root) return;
Order(root->left, min_diff, pre);
if(pre && root->val - pre->val < min_diff) {
min_diff = root->val - pre->val;
}
pre = root;
Order(root->right, min_diff, pre);
}
int getMinimumDifference(TreeNode* root) {
int result = INT_MAX;
TreeNode* pre = nullptr;
Order(root, result, pre);
return result;
}
};
非递归
// c++
/**
* 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 {
public:
int getMinimumDifference(TreeNode* root) {
stack<TreeNode*> st;
int min_diff = INT_MAX;
TreeNode* pre = nullptr;
while(root || !st.empty()){
if(root){
st.push(root);
root = root->left;
}else{
root = st.top();
st.pop();
if(pre && root->val - pre->val < min_diff) min_diff = root->val - pre->val;
pre = root;
root = root->right;
}
}
return min_diff;
}
};
501. 二叉搜索树中的众数
和上题一样,二叉搜索树,中序遍历是单调不减序列,众数在中序遍历中连续出现次数最多的元素,因此使用中序遍历记录元素出现次数,将出现最多元素放入列表。题目提示众数不止一个,所以需要考虑如何使用一次遍历找出所有众数。
假设当前记录的众数出现的次数为maxcnt,在中序遍历时记录每个元素的出现次数,当有元素出现次数与maxcnt相等时,将当前元素放入结果列表;当有元素出现次数大于maxcnt时,清空结果列表并放入当前元素,maxcnt修改为当前元素出现次数。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
// c++
/**
* 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 {
public:
vector<int> findMode(TreeNode* root) {
vector<int> result;
int cnt=0, maxcnt=0;
stack<TreeNode*> st;
int min_diff = INT_MAX;
TreeNode* pre = nullptr;
while(root || !st.empty()){
if(root){
st.push(root);
root = root->left;
}else{
root = st.top();
st.pop();
if(pre && root->val == pre->val ) cnt++;
else if(!pre){
cnt++;
pre = root;
}else{
cnt=1;
pre = root;
}
if(cnt == maxcnt) result.emplace_back(root->val);
else if(cnt>maxcnt) {
// 清空结果列表
result.clear();
result.emplace_back(root->val);
maxcnt = cnt;
}
root = root->right;
}
}
return result;
}
};
*236. 二叉树的最近公共祖先
本题需要再找到目标节点后回溯,后序遍历符合回溯要求。
- 当找到目标节点时返回目标节点
- 分别递归查看左右子树并记录返回值,分别为lt和rt
- 若左右子树返回值均不为空,则说明当前节点就是最近的公共祖先
- 若左右子树返回值有一个为空,则说明两个节点是在同一颗子树中找到的(说明其是目标节点的公共祖先,但不是最近的),则返回不为空的子树的返回值。
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
// 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:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(!root) return nullptr;
if(root == p || root == q) return root;
TreeNode* lt = lowestCommonAncestor(root->left, p, q);
TreeNode* rt = lowestCommonAncestor(root->right, p, q);
if(lt && rt) return root;
if(lt) return lt;
if(rt) return rt;
// 叶结点
return nullptr;
}
};