530 递归的方法 也先放到中序遍历的一个数组里面之后再遍历
//递归
class Solution {
void traversal(TreeNode* root, vector<int>& result) {
if (root == nullptr) return;
traversal(root->left, result);
result.push_back(root->val);
traversal(root->right, result);
}
public:
int getMinimumDifference(TreeNode* root) {
vector<int> result;
traversal(root, result);
int min_res = INT_MAX;
for (int i=1; i<result.size(); i++) {
min_res = min(min_res, abs(result[i]-result[i-1]));
}
return min_res;
}
};
迭代法就是用栈写中序遍历 一样的套路
//迭代
class Solution {
public:
int getMinimumDifference(TreeNode* root) {
stack<TreeNode*> stack;
vector<int> result;
TreeNode* curr = root;
while (curr!=nullptr || !stack.empty()) {
if (curr!=nullptr) {
stack.push(curr);
curr = curr->left;
}
else {
curr = stack.top();
stack.pop();
result.push_back(curr->val);
curr = curr->right;
}
}
int min_res = INT_MAX;
for (int i=1; i<result.size(); i++) {
if (result[i]-result[i-1]<min_res) {
min_res = result[i]-result[i-1];
}
}
return min_res;
}
};
501 我自己写的迭代法 可是要遍历两边 会比较慢
class Solution {
public:
vector<int> findMode(TreeNode* root) {
stack<TreeNode*> stack;
TreeNode* curr = root;
vector<int> result;
while (curr!=nullptr || !stack.empty()) {
if (curr!=nullptr) {
stack.push(curr);
curr = curr->left;
}
else {
curr = stack.top();
stack.pop();
result.push_back(curr->val);
curr = curr->right;
}
}
int count=1;
int max_count = count;
vector<int>res;
for (int i=1; i<result.size(); i++) {
if (result[i] == result[i-1]) {
count++;
}
else {
if (count>max_count) {
res.clear();
max_count = count;
res.push_back(result[i-1]);
}
else if (count == max_count) {
res.push_back(result[i-1]);
}
count = 1;
}
}
if (count>max_count) {
res.clear();
max_count = count;
res.push_back(result[result.size()-1]);
}
else if (count == max_count) {
res.push_back(result[result.size()-1]);
}
return res;
}
};
看了代码随想录的做法 发现可以只遍历一次 用pre指针来写
class Solution {
private:
int count;
int max_count = INT_MIN;
vector<int>res;
TreeNode* pre = NULL;
void traversal (TreeNode* root) {
if (root==nullptr) return;
traversal(root->left);
TreeNode* curr = root;
if (pre == NULL) count = 1;
else if (pre->val==curr->val) count++;
else count = 1;
if (count == max_count) {
res.push_back(curr->val);
}
else if (count>max_count) {
max_count = count;
res.clear();
res.push_back(curr->val);
}
pre = curr;
traversal(root->right);
}
public:
vector<int> findMode(TreeNode* root) {
traversal(root);
return res;
}
};
236
理解逻辑之后就不难了 cr to 代码随想录的总结
-
求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。
-
在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。
-
要理解如果返回值left为空,right不为空为什么要返回right,为什么可以用返回right传给上一层结果。
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == p || root == q || root == NULL) return root;
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if (left && right) return root;
if (!left) return right;
if (!right) return left;
return root;
}
};
自我总结:
1. 用后序遍历 向上回溯
2. 找到p or q的子树向上return找到的值 (如果另外一个要找的在他的子树里也不影响)
3. 左右子树都找不到的话return null 用之判断
4. 如果左右子树分别找到,向上return root(即最近的公共祖先答案)
5. 如果左子树找到右子树没找到,把左子树的往上传 反之亦然