【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]

题目链接

文章目录

    • Python3
      • 方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯
      • 方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯
      • 方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup O(n)O(1)⟯
    • C++
      • 方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯
      • 方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯
        • stack 类
      • 方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup O(n)O(1)⟯

【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第1张图片

【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第2张图片
【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第3张图片
【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第4张图片

二叉树的前序遍历:按照访问根节点——左子树——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。

Python3

方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第5张图片

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        """ 前序遍历 [ 根 左子树 右子树 ]  递归"""
        def preorder(node):
            if not node:
                return 
            ans.append(node.val)
            preorder(node.left)
            preorder(node.right)

        ans = []
        preorder(root)
        return ans        

方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

递归:隐式地维护了一个栈
迭代:显式地将这个栈模拟出来

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        """ 前序遍历 [根 左子树  右子树]  迭代"""

        ans =[]
        stack = []
        
        cur = root
        while cur or stack:
            while cur:
                ans.append(cur.val)  # 根 加入 ans  
                stack.append(cur)  
                cur = cur.left  # 左

            cur = stack.pop() 
            cur = cur.right  # 右

        return ans 

方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup O(n)O(1)⟯

【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第6张图片

参考链接

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        """ 前序遍历 [根 左子树 右子树 ]  Morris  O(N) O(1)"""
        ans = []
        cur, pre = root, None 
        while cur:
            if not cur.left:
                ans.append(cur.val) ##
                cur = cur.right 

            # 有左孩子
            else:
                # 找 pre 
                pre = cur.left 
                while pre.right and pre.right != cur:
                    pre = pre.right  
                if not pre.right: ## 找到 mostright
                    pre.right = cur
                    ans.append(cur.val) ## 前序遍历
                    cur = cur.left 
                else:
                    pre.right = None 
                   # ans.append(cur.val)  中序遍历
                    cur = cur.right 
        return ans 

【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第7张图片

C++

方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

/**
 * 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:
    // 子 模块 
    void preorder(TreeNode *node, vector<int> &ans){
        if (node == nullptr){
            return; 
        }
        ans.emplace_back(node->val);
        preorder(node->left, ans);
        preorder(node->right, ans);
    }

    // 主模块
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        preorder(root, ans);
        return ans;
    }
};

方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup O(n)⟯

/**
 * 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:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        if (root == nullptr){
            return ans;
        }

        stack<TreeNode*> stk;  // 栈 的定义
        TreeNode* cur = root;
        while (cur != nullptr || !stk.empty()){
            while (cur != nullptr){
                ans.emplace_back(cur->val); // 根
                stk.emplace(cur);  //  入栈
                cur = cur->left; // 左
            }

            // 开始 栈 弹出
            cur = stk.top(); // 取 栈顶元素
            stk.pop();    // 不返回 值   
            cur = cur->right; // 右
        }   
        return ans;
    }
};
stack 类

stack 类 文档链接
【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]_第8张图片
Python3 的 list 会返回
文档
在这里插入图片描述

lis = [1, 2, 3, 4]
print(lis.pop())

在这里插入图片描述

方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup O(n)O(1)⟯

/**
 * 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:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> ans;
        TreeNode* cur = root;
        TreeNode* pre = nullptr;

        while (cur != nullptr){
            if (cur->left == nullptr){ // 情况1
                ans.emplace_back(cur->val);
                cur = cur->right;
            }
            else{// 有左孩子  // 情况 2
                // 找 pre 
                pre = cur->left;
                while (pre->right != nullptr && pre->right != cur){
                    pre = pre->right;
                }
                if (pre->right == nullptr){ // 情况 2(1)
                    pre->right = cur;
                    ans.emplace_back(cur->val);
                    cur = cur->left;
                }
                else{  // 情况 2(2)
                    pre->right = nullptr;
                    cur = cur -> right;
                    
                }
            }
        }

    return ans;
    }
};

你可能感兴趣的:(#,编程练习合集,LeetCode,Python3,C++)