刷题记录
- 530. 二叉搜索树的最小绝对差
- 递归
- 非递归
- 501. 二叉搜索树中的众数
- *236. 二叉树的最近公共祖先
530. 二叉搜索树的最小绝对差
leetcode题目地址
如果是一颗普通树,则使用暴力求解法:遍历树并保存树种每个节点的值,排序后找差值最小的元素。
本题给的是一颗二叉搜索树(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. 二叉搜索树中的众数
leetcode题目地址
和上题一样,二叉搜索树,中序遍历是单调不减序列,众数在中序遍历中连续出现次数最多的元素,因此使用中序遍历记录元素出现次数,将出现最多元素放入列表。题目提示众数不止一个,所以需要考虑如何使用一次遍历找出所有众数。
假设当前记录的众数出现的次数为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. 二叉树的最近公共祖先
leetcode题目地址
本题需要再找到目标节点后回溯,后序遍历符合回溯要求。
- 当找到目标节点时返回目标节点
- 分别递归查看左右子树并记录返回值,分别为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;}
};