代码随想录算法训练营第21天|530 501 236

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 代码随想录的总结

  1. 求最小公共祖先,需要从底向上遍历,那么二叉树,只能通过后序遍历(即:回溯)实现从底向上的遍历方式。

  2. 在回溯的过程中,必然要遍历整棵二叉树,即使已经找到结果了,依然要把其他节点遍历完,因为要使用递归函数的返回值(也就是代码中的left和right)做逻辑判断。

  3. 要理解如果返回值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. 如果左子树找到右子树没找到,把左子树的往上传 反之亦然

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值