530. 二叉搜索树的最小绝对差(题目链接:力扣)
思路:因为是二叉搜索树,所以只需要额外用一个指针保存前一个指向的节点,每次遍历将本节点与前一个节点的值相减得到差值,遍历完整颗二叉搜索树,就可以得到结果。
int lastValue = -1;
int traversal(TreeNode* root, int minValue){
if(root->left) minValue = traversal(root->left, minValue);
if(lastValue != -1 && root->val - lastValue < minValue) minValue = root->val - lastValue;
lastValue = root->val;
if(root->right) minValue = traversal(root->right, minValue);
return minValue;
}
int getMinimumDifference(TreeNode* root) {
return traversal(root, INT_MAX);
}
int getMinimumDifference(TreeNode* root) {
stack<TreeNode*> st;
TreeNode* cur = root;
int result = INT_MAX;
int lastValue = -1;
while(!st.empty() || cur){
while(cur){
st.push(cur);
cur = cur->left;
}
cur = st.top();
st.pop();
if(lastValue != -1 && cur->val - lastValue < result) result = cur->val - lastValue;
lastValue = cur->val;
cur = cur->right;
}
return result;
}
501. 二叉搜索树中的众数(题目链接:力扣)
思路:因为是二叉搜索树,所以只遍历一次即可,碰到相同节点计数,如果某次计数最大,就将前面存储好了的值全部丢掉,把本次计数最大对应的节点的值存下来(本来我是用stack存放中间结果,最后再一次性倒进vector的,后来看了卡哥解析才知道可以直接用vector,每次清空的时候直接vector.clear()就可以了)。如果不是二叉搜索树需要遍历两次,第一次遍历用map计数,第二次把计数到map中最大值对应的节点值存下来。
int maxCount = 0;
int lastCount = 0;
TreeNode* pre = NULL;
stack<int> st;
void traversal(TreeNode* root){
if(root->left) traversal(root->left);
if(pre && root->val == pre->val) lastCount++;
else lastCount = 1;
if(lastCount > maxCount){
maxCount = lastCount;
while(!st.empty()){
st.pop();
}
st.push(root->val);
}else if(lastCount == maxCount){
st.push(root->val);
}
pre = root;
if(root->right) traversal(root->right);
}
vector<int> findMode(TreeNode* root) {
traversal(root);
vector<int> vec;
while(!st.empty()){
vec.push_back(st.top());
st.pop();
}
return vec;
}
vector<int> findMode(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
stack<int> stNums;
int maxCount = 0;
int lastCount = 0;
TreeNode* cur = root;
TreeNode* pre = NULL;
while(!st.empty() || cur){
while(cur){
st.push(cur);
cur = cur->left;
}
cur = st.top();
st.pop();
if(pre && cur->val == pre->val) lastCount++;
else lastCount = 1;
if(lastCount > maxCount){
maxCount = lastCount;
while(!stNums.empty()){
stNums.pop();
}
stNums.push(cur->val);
}else if(lastCount == maxCount){
stNums.push(cur->val);
}
pre = cur;
cur = cur->right;
}
while(!stNums.empty()){
result.push_back(stNums.top());
stNums.pop();
}
return result;
}
236. 二叉树的最近公共祖先(题目链接:力扣)
思路:这道题想了很久(主要卡在了记录路径这里,后来深刻理解了回溯,并且这种记录中间路径的做法一定要用全局变量来存,不然回溯会导致丢失数据),先找到p,并把路径存进stack,然后从stack中依次取出节点,判断该节点下是否能找到q,找到就返回。
stack<TreeNode*> st;
bool flag = false;
void traversal1(TreeNode* root, TreeNode* p, stack<TreeNode*>& stTmp){
if(root == p){
stTmp.push(root);
st = stTmp;
flag = true;
}
if(!flag && root->left){
stTmp.push(root);
traversal1(root->left, p, stTmp);
stTmp.pop();
}
if(!flag && root->right){
stTmp.push(root);
traversal1(root->right, p, stTmp);
stTmp.pop();
}
}
bool traversal2(TreeNode* root, TreeNode* q){
if(root == NULL) return false;
return root == q || traversal2(root->left, q) || traversal2(root->right, q);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
stack<TreeNode*> stTmp;
traversal1(root, p, stTmp);
while(!st.empty()){
TreeNode* cur = st.top();
if(traversal2(cur, q)) return cur;
st.pop();
}
return root;
}
后来看了解析才发现真tm简单,主打一个从叶子节点回溯,找到值然后返回。
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL || root == q || root == p) 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 left;
if(left == NULL && right != NULL) return right;
return NULL;
}