1.二叉树的深度

    int TreeDepth(TreeNode* root) {
        if (!root) return 0;
        int l = TreeDepth(root->left);
        int r = TreeDepth(root->right);
        return max(l, r) + 1;
    }

2.按之字形顺序打印二叉树

    vector<vector<int> > Print(TreeNode* root) {
        vector<vector<int>> res;
        if (!root) return res;
         
        queue<TreeNode*> q;
        int turn = 1;
        q.push(root);
        while (q.size()) {
            vector<int> path;
            int n = q.size();
            turn++;
            for (int i = 0; i < n; ++i) {
                auto node = q.front();
                q.pop();
                path.emplace_back(node->val);
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            if (turn & 1) {
                reverse(begin(path), end(path));
            }
            res.emplace_back(path);
        }
         
        return res;
    }

3.二叉搜索树的第K个节点

public:
    vector<int> vec;
    void traval(TreeNode* root) {
        if (!root) return;
        traval(root->left);
        vec.emplace_back(root->val);
        traval(root->right);
    }
    int KthNode(TreeNode* root, int k) {
        if (!root or k == 0) return -1;
        traval(root);
        if (vec.size() < k) return -1;
        return vec[k - 1];
    }
};

4.重建二叉树

前序遍历 + 中序遍历

    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if (pre.empty()) return nullptr;
        auto root = new TreeNode(pre[0]);
        int idx = distance(vin.begin(), find(vin.begin(), vin.end(), pre[0]));
        vector<int> leftPre(pre.begin() + 1, pre.begin() + idx + 1);
        vector<int> rightPre(pre.begin() + idx + 1, pre.end());
        vector<int> leftVin(vin.begin(), vin.begin() + idx);
        vector<int> rightVin(vin.begin() + idx + 1, vin.end());
         
        root->left = reConstructBinaryTree(leftPre, leftVin);
        root->right = reConstructBinaryTree(rightPre, rightVin);
        return root;
    }

哈希表加速

class Solution {
    unordered_map<int, int> umap;
        TreeNode* dfs(vector<int>&pre, vector<int>& in, int pl, int pr, int il, int ir){
        if(pl > pr) return nullptr;
        //通过前序遍历找到根节点
        auto root = new TreeNode(pre[pl]);
        //找到根节点在中序遍历中的位置
        //该位置的左边就是根节点的左子树中序遍历,右边就是右子树的中序遍历
        int k = umap[pre[pl]] - il;
        //递归创建左右子树
        root->left = dfs(pre, in, pl + 1, pl + k, il, il + k - 1);
        root->right = dfs(pre, in, pl + k + 1, pr,il + k + 1, ir);
         
        return root;
    }
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
        if (pre.empty()) return nullptr;
        int n = pre.size();
         
        for (int i = 0; i < vin.size(); ++i) {
            umap[vin[i]] = i;
        }
         
        return dfs(pre, vin, 0, n - 1, 0, n - 1);
    }
};

5.树的子结构

class Solution {
    bool isPart(TreeNode* p1, TreeNode* p2) {
        if (!p2) return true;
        if (!p1 or p1->val != p2->val) return false;
        return isPart(p1->left, p2->left) and isPart(p1->right, p2->right);
    }
public:
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) {
        if (!pRoot1 or !pRoot2) return false;
        if (isPart(pRoot1, pRoot2)) return true;
        return HasSubtree(pRoot1->left, pRoot2) or HasSubtree(pRoot1->right, pRoot2);
    }
};

6.二叉树的镜像

    TreeNode* Mirror(TreeNode* pRoot) {
        if (!pRoot) return nullptr;
        swap(pRoot->left, pRoot->right);
        Mirror(pRoot->left);
        Mirror(pRoot->right);
        return pRoot;
    }

7.二叉树中和为某一值的路径Ⅰ

    bool hasPathSum(TreeNode* root, int sum) {
        if (!root) return false;
        sum -= root->val;
        if (!root->left and !root->right) {
            if (sum == 0) return true;
            else return false;
        }
        return hasPathSum(root->left, sum) or hasPathSum(root->right, sum);
    }

8.二叉树中和为某一值的路径Ⅱ

class Solution {
    vector<vector<int>> res;
    vector<int> path;
    void dfs(TreeNode* root, int sum) {
        if (!root) return;
        path.push_back(root->val);
        sum -= root->val;
        //如果已经到最后一层了并且sum已经减到了0,那么就是答案
        if (!root->left && !root->right && !sum) res.push_back(path);
        dfs(root->left, sum);
        dfs(root->right, sum);
        path.pop_back();
    }
public:
    vector<vector<int>> FindPath(TreeNode* root,int sum) {
        dfs(root, sum);
        return res;
    }
};

9.二叉树中和为某一值的路径Ⅲ

class Solution {
    int res = 0;
    void dfs(TreeNode* root, int sum) {
        if (!root) return;
        if (sum == root->val) ++res;
        dfs(root->left, sum - root->val);
        dfs(root->right, sum - root->val);
    }
public:
    int FindPath(TreeNode* root, int sum) {
        if (!root) return res;
        dfs(root, sum);
        FindPath(root->left, sum);
        FindPath(root->right, sum);
        return res;
    }
};

10.二叉搜索树与双向链表

class Solution {
    vector<TreeNode*> vec;
    void inorder(TreeNode* pRoot) {
        if (!pRoot) return;
        inorder(pRoot->left);
        vec.emplace_back(pRoot);
        inorder(pRoot->right);
    }
public:
    TreeNode* Convert(TreeNode* pRoot) {
        if (!pRoot) return nullptr;
        inorder(pRoot);
        auto head = vec[0];
        auto cur = head;
        head->left = nullptr;
        for (int i = 1; i < vec.size(); ++i) {
            cur->right = vec[i];
            vec[i]->left = cur;
            cur = cur->right;
        }
        return head;
    }
};

11.序列化二叉树

感觉层序遍历更容易理解

class Solution {
public:
    char* Serialize(TreeNode *root) {    
        string s;
        queue<TreeNode*> q;
        q.push(root);
        while (q.size()) {
            auto node = q.front(); q.pop();
            if (!node) {
                s += "#,";
                continue;
            }
            s += to_string(node->val) + ',';
            q.push(node->left);
            q.push(node->right);
        }
        char *res = new char[s.size() + 1];
        strcpy(res, s.c_str());
        return res;
    }
    TreeNode* Deserialize(char *str) {
        if (!str or str[0] == '#') return nullptr;
        string s = str;
        queue<TreeNode*> q;
        TreeNode* root = new TreeNode(atoi(s.c_str()));
        s = s.substr(s.find_first_of(',') + 1);
        q.push(root);
        while (s.size() and q.size()) {
            auto node = q.front(); q.pop();
            
            if (s[0] == '#') {
                node->left = nullptr;
                s = s.substr(2);
            } else {
                node->left = new TreeNode(atoi(s.c_str()));
                q.push(node->left);
                s = s.substr(s.find_first_of(',') + 1);
            }
            
            if (s[0] == '#') {
                node->right = nullptr;
                s = s.substr(2);
            } else {
                node->right = new TreeNode(atoi(s.c_str()));
                q.push(node->right);
                s = s.substr(s.find_first_of(',') + 1);
            }
        }
        return root;
    }
};

12.对称二叉树

class Solution {
    bool check(TreeNode* l, TreeNode* r) {
        if (!l || !r) return !l and !r;
        if (l->val != r->val) return false;
        return check(l->left, r->right) and check(l->right, r->left);
    }
public:
    bool isSymmetrical(TreeNode* pRoot) {
        if (!pRoot) return true;
        return check(pRoot->left, pRoot->right);
    }
};

13.二叉树的先序中序后序遍历迭代法

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

    vector<int> inOrder(TreeNode* root) {
        if (!root) return {};
        vector<int> res;
        stack<TreeNode*> stk;
        auto cur = root;
        while (!stk.empty() or cur) {
            if (cur) {
                stk.push(cur);
                cur = cur->left;
            } else {
                cur = stk.top(); stk.pop();
                res.push_back(cur->val);
                cur = cur->right;
            }
        }
        return res;
    }
    
    vector<int> postOrder(TreeNode* root) {
        if (!root) return {};
        vector<int> res;
        stack<TreeNode*> stk;
        stk.push(root);
        while (!stk.empty()) {
            auto node = stk.top(); stk.pop();
            res.push_back(node->val);
            if (node->left) stk.push(node->left);
            if (node->right) stk.push(node->right);
        }
        reverse(res.begin(), res.end());
        return res;
    }
public:

    vector<vector<int> > threeOrders(TreeNode* root) {
        vector<vector<int>> res;
        res.push_back(preOrder(root));
        res.push_back(inOrder(root));
        res.push_back(postOrder(root));
        return res;
    }
};

14.二叉树的最近公共祖先

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //root为空或者遍历到空的叶节点
        if (!root) return root;
        if (p == root or q == root) return root;
        //左边找一找
        auto L = lowestCommonAncestor(root->left, p, q);
        //右边找一找
        auto R = lowestCommonAncestor(root->right, p, q);
        if (L and R) return root;
        else if (L) return L;
        else if (R) return R;
        return nullptr;
    }
全部评论

相关推荐

09-29 17:44
已编辑
蔚来_测(准入职员工)
//鲨鱼辣椒:见不了了我实习了四个月上周再投筛选了一天就给我挂了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务