【Leetcode】二叉树

二叉树的非递归遍历

cpp

/**
 * 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) {}
 * };
 */

python

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

前序

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if (root == nullptr) return res;
        stack<TreeNode*> stk;
        TreeNode* node = root;
        while (!stk.empty() || node != nullptr) {
            while (node != nullptr) {
            	stk.push(node);
                res.push_back(node->val);       
                node = node->left;
            }
            node = stk.top();
            stk.pop();
            node = node->right;
        }
        return res;
    }
};

中序

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*> st;
        TreeNode* cur = root;
        while(cur or !st.empty()){
            while(cur){
                st.push(cur);
                cur = cur->left;
            } 
            cur = st.top();
            res.push_back(cur->val);
            st.pop();
            cur = cur->right;
        }
        return res;
    }
};

后序

/*
1. 后序非递归遍历顺序:左右根
2. 用堆栈来存储结点时,必须分清返回根节点时 是从左子树返回还是右子树返回。
3. 所以使用辅助指针r,指向最近访问过的结点。
*/
class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        vector<int> res;
        if (root == nullptr) return res;
        stack<TreeNode *> stk;
        TreeNode *cur = root;
        TreeNode *prev = nullptr; //是从左子树返回,还是右子树
        while (cur != nullptr || !stk.empty()) {
            while (cur != nullptr) {
                stk.push(cur);
                cur = cur->left;
            }
            cur = stk.top(); //最左边的节点
            stk.pop();
            if (cur->right == nullptr || cur->right == prev) { //是从右子树返回
                res.push_back(cur->val);
                prev = cur;
                cur = nullptr;
            } else {
                stk.emplace(cur); //根结点
                cur = cur->right;
            }
        }
        return res;
    }
};

114. 二叉树展开为链表

在这里插入图片描述

class Solution {
public:
    //先序遍历后再连接起来
    vector<TreeNode*> list;
    void flatten(TreeNode* root) {
        if(root==nullptr) return;
        preorder(root);
        int len = list.size();
        for(int i=0; i<len-1; ++i){
            list[i]->left = nullptr;
            list[i]->right = list[i+1];
        }
        return;
    }

    void preorder(TreeNode* root){
        if(root==nullptr) return;
        list.push_back(root);
        preorder(root->left);
        preorder(root->right);
    }
};

二叉树的路径问题

437. 路径总和 III

在这里插入图片描述

class Solution {
public:
    int res = 0;
    int pathSum(TreeNode* root, int targetSum) {
        if(root==nullptr) return 0;
        pathroot(root, targetSum);
        pathSum(root->left, targetSum);
        pathSum(root->right, targetSum);
        return res;
    }

    void pathroot(TreeNode* root, int targetSum){
        if(root==nullptr) return;
        if(targetSum-root->val==0) res++;
        pathroot(root->left, targetSum-root->val);
        pathroot(root->right, targetSum-root->val);
    }
};

662. 二叉树最大宽度

/**
 * 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 widthOfBinaryTree(TreeNode* root) {
        if(!root) return 0;
        queue<pair<TreeNode*, int> > q;
        q.push({root, 1});
        int ans = 1;
        while(q.size()) {
            // 遍历每层的时候设置左顶点,右顶点
            int n = q.size();
            int l = q.front().second, r;

            for(int i = 0; i < n; i ++) {
                auto x = q.front();
                q.pop();
                auto ver = x.first;
                // 将每层节点初始化从一开始计算
                auto pos = x.second - l + 1;
                r = x.second;
                if(ver -> left) q.push({ver -> left, pos * 2});
                if(ver -> right) q.push({ver -> right, pos * 2 + 1});
            }
            ans = max(ans, r - l + 1);
        }
        return ans;
    }
};

剑指 Offer 26. 树的子结构

1、自顶向下:
顾名思义,就是从某一个节点(不一定是根节点),从上向下寻找路径,到某一个节点(不一定是叶节点)结束
257. 二叉树的所有路径
面试题 04.12. 求和路径
112. 路径总和
113. 路径总和 II
437. 路径总和 III
988. 从叶结点开始的最小字符串
2、非自顶向下:
就是从任意节点到任意节点的路径,不需要自顶向下
124. 二叉树中的最大路径和
687. 最长同值路径
543. 二叉树的直径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值