【C++】二叉树进阶OJ题

606. 根据二叉树创建字符串

https://leetcode.cn/problems/construct-string-from-binary-tree/

//606. 根据二叉树创建字符串
class Solution {
public:
    string tree2str(TreeNode* root) {
        if (root == nullptr)
            return "";

        string str = to_string(root->val);
        if (root->left || root->right)
        {
            str += '(';
            str += tree2str(root->left);
            str += ')';
        }

        if (root->right)
        {
            str += '(';
            str += tree2str(root->right);
            str += ')';
        }

        return str;
    }
};

102. 二叉树的层序遍历

https://leetcode.cn/problems/binary-tree-level-order-traversal/

//102. 二叉树的层序遍历
class Solution2 {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> q;
        int levelSize = 0;
        if (root)
        {
            q.push(root);
            levelSize++;
        }
        vector<vector<int>> vv;

        while (!q.empty())
        {
            vector<int> v;
            while (levelSize--)
            {
                TreeNode* front = q.front();
                q.pop();
                v.push_back(front->val);

                if (front->left)
                    q.push(front->left);
                if (front->right)
                    q.push(front->right);
            }
            vv.push_back(v);
            levelSize = q.size();
        }
        return vv;
    }
};

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

https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/

//236. 二叉树的最近公共祖先--法一
class Solution3 {
public:
    bool InTree(TreeNode* root, TreeNode* x)
    {
        if (root == nullptr)
            return false;

        return root == x || InTree(root->left, x) || InTree(root->right, x);
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == nullptr)
            return nullptr;
        if (p == root || q == root)
            return root;

        bool pInLeft = InTree(root->left, p);
        bool pInRight = !pInLeft;

        bool qInLeft = InTree(root->left, q);
        bool qInRight = !qInLeft;

        if ((pInLeft && qInRight) || (pInRight && qInLeft))
            return root;
        else if (qInLeft && pInLeft)
            return lowestCommonAncestor(root->left, p, q);
        else
            return lowestCommonAncestor(root->right, p, q);
    }
};

//236. 二叉树的最近公共祖先--法二
class Solution4 {
public:
    //注意路径的提取
    bool GetPath(TreeNode* root, TreeNode* x, stack<TreeNode*>& path)
    {
        if (root == nullptr)
            return false;

        path.push(root);

        if (root == x)
            return true;

        if (GetPath(root->left, x, path))
            return true;

        if (GetPath(root->right, x, path))
            return true;

        path.pop();
        return false;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        stack<TreeNode*> qPath;
        stack<TreeNode*> pPath;
        GetPath(root, q, qPath);
        GetPath(root, p, pPath);

        while (qPath.size() != pPath.size())
        {
            if (qPath.size() > pPath.size())
                qPath.pop();
            else
                pPath.pop();
        }
        while (qPath.top() != pPath.top())
        {
            qPath.pop();
            pPath.pop();
        }
        return qPath.top();
    }
};

JZ36 二叉搜索树与双向链表

https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&&tqId=11179&rp=1&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking

//JZ36 二叉搜索树与双向链表
//中序,记录前驱,改变链接关系
class Solution5 {
public:
    void MakeList(TreeNode* cur, TreeNode*& prev)
    {
        if (cur == nullptr)
            return;
        MakeList(cur->left, prev);
        cur->left = prev;
        if (prev)
            prev->right = cur;
        prev = cur;
        MakeList(cur->right, prev);
        return;
    }

    TreeNode* Convert(TreeNode* pRootOfTree) {
        TreeNode* prev = nullptr;
        MakeList(pRootOfTree, prev);
        TreeNode* head = pRootOfTree;
        while (head && head->left)
        {
            head = head->left;
        }
        return head;
    }
};

105. 从前序与中序遍历序列构造二叉树

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

//105. 从前序与中序遍历序列构造二叉树
class Solution {
public:
    TreeNode* _buildTree(vector<int>& preorder, vector<int>& inorder, int& prei, int inbegin, int inend) {
        if (inbegin > inend)
            return nullptr;
        TreeNode* newnode = new TreeNode(preorder[prei]);

        //分割区间
        int rooti = inbegin;
        while (rooti <= inend)
        {
            if (inorder[rooti] == preorder[prei])
                break;
            rooti++;
        }

        prei++;
        newnode->left = _buildTree(preorder, inorder, prei, inbegin, rooti - 1);
        newnode->right = _buildTree(preorder, inorder, prei, rooti + 1, inend);
        return newnode;

    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int prei = 0;
        return _buildTree(preorder, inorder, prei, 0, inorder.size() - 1);
    }
};

106. 从中序与后序遍历序列构造二叉树

https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

//106. 从中序与后序遍历序列构造二叉树
class Solution {
public:
    TreeNode* _buildTree(vector<int>& inorder, vector<int>& postorder, int& posti, int inbegin, int inend) {
        if (inbegin > inend)
            return nullptr;
        TreeNode* newnode = new TreeNode(postorder[posti]);
        int rooti = inbegin;
        while (rooti <= inend)
        {
            if (postorder[posti] == inorder[rooti])
                break;
            rooti++;
        }
        posti--;
        //这里是后序,先链接右结点,再链接左结点
        newnode->right = _buildTree(inorder, postorder, posti, rooti + 1, inend);
        newnode->left = _buildTree(inorder, postorder, posti, inbegin, rooti - 1);

        return newnode;
    }
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        int posti = postorder.size() - 1;
        return _buildTree(inorder, postorder, posti, 0, inorder.size() - 1);
    }
};

非递归实现二叉树遍历(重点–后序)

https://leetcode.cn/problems/binary-tree-postorder-traversal/

//前序非递归迭代实现
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> s;
        vector<int> v;

        //前序非递归
        while (root || !s.empty())
        {
            while (root)
            {
                //左路结点入栈
                s.push(root);
                v.push_back(root->val);
                root = root->left;
            }
            TreeNode* top = s.top();
            s.pop();
            root = top->right;
        }
        return v;
    }
};

//中序非递归实现
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> s;
        vector<int> v;

        //中序非递归
        while (root || !s.empty())
        {
            while (root)
            {
                //左路结点入栈
                s.push(root);
                root = root->left;
            }
            TreeNode* top = s.top();
            s.pop();
            v.push_back(top->val);
            root = top->right;
        }
        return v;
    }
};

//**后序非递归迭代实现
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        stack<TreeNode*> s;
        vector<int> v;

        //后序非递归

        //prev记录上一次访问结点
        TreeNode* prev = nullptr;
        while (root || !s.empty())
        {
            while (root)
            {
                //右路结点入栈
                s.push(root);
                root = root->left;
            }
            TreeNode* top = s.top();

            if (top->right == nullptr || top->right == prev)
            {
                v.push_back(top->val);
                s.pop();
                //访问则更新prev
                prev = top;
            }
            else
            {
                root = top->right;
            }
        }
        return v;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值