diff --git a/solution/0000-0099/0094.Binary Tree Inorder Traversal/README.md b/solution/0000-0099/0094.Binary Tree Inorder Traversal/README.md index bb26dc9cb3767..a96d349ff0b52 100644 --- a/solution/0000-0099/0094.Binary Tree Inorder Traversal/README.md +++ b/solution/0000-0099/0094.Binary Tree Inorder Traversal/README.md @@ -67,7 +67,6 @@ class Solution: if root is None: return dfs(root.left) - nonlocal ans ans.append(root.val) dfs(root.right) diff --git a/solution/0000-0099/0094.Binary Tree Inorder Traversal/README_EN.md b/solution/0000-0099/0094.Binary Tree Inorder Traversal/README_EN.md index 113495b7645e8..dba84cd494f23 100644 --- a/solution/0000-0099/0094.Binary Tree Inorder Traversal/README_EN.md +++ b/solution/0000-0099/0094.Binary Tree Inorder Traversal/README_EN.md @@ -62,7 +62,6 @@ class Solution: if root is None: return dfs(root.left) - nonlocal ans ans.append(root.val) dfs(root.right) diff --git a/solution/0000-0099/0094.Binary Tree Inorder Traversal/Solution.py b/solution/0000-0099/0094.Binary Tree Inorder Traversal/Solution.py index 7a383bea3c861..a0820b1ccc626 100644 --- a/solution/0000-0099/0094.Binary Tree Inorder Traversal/Solution.py +++ b/solution/0000-0099/0094.Binary Tree Inorder Traversal/Solution.py @@ -10,7 +10,6 @@ def dfs(root): if root is None: return dfs(root.left) - nonlocal ans ans.append(root.val) dfs(root.right) diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/README.md b/solution/0100-0199/0144.Binary Tree Preorder Traversal/README.md index 35ad34d266cc0..d5ae90350428e 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/README.md +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/README.md @@ -60,7 +60,11 @@ ## 解法 -### 方法一 +### 方法一:递归遍历 + +我们先访问根节点,然后递归左子树和右子树。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数,空间复杂度主要取决于递归调用的栈空间。 @@ -76,7 +80,6 @@ class Solution: def dfs(root): if root is None: return - nonlocal ans ans.append(root.val) dfs(root.left) dfs(root.right) @@ -103,10 +106,9 @@ class Solution: * } */ class Solution { - private List ans; + private List ans = new ArrayList<>(); public List preorderTraversal(TreeNode root) { - ans = new ArrayList<>(); dfs(root); return ans; } @@ -138,25 +140,15 @@ class Solution { public: vector preorderTraversal(TreeNode* root) { vector ans; - while (root) { - if (!root->left) { - ans.push_back(root->val); - root = root->right; - } else { - TreeNode* prev = root->left; - while (prev->right && prev->right != root) { - prev = prev->right; - } - if (!prev->right) { - ans.push_back(root->val); - prev->right = root; - root = root->left; - } else { - prev->right = nullptr; - root = root->right; - } + function dfs = [&](TreeNode* root) { + if (!root) { + return; } - } + ans.push_back(root->val); + dfs(root->left); + dfs(root->right); + }; + dfs(root); return ans; } }; @@ -171,28 +163,18 @@ public: * Right *TreeNode * } */ -func preorderTraversal(root *TreeNode) []int { - var ans []int - for root != nil { - if root.Left == nil { - ans = append(ans, root.Val) - root = root.Right - } else { - prev := root.Left - for prev.Right != nil && prev.Right != root { - prev = prev.Right - } - if prev.Right == nil { - ans = append(ans, root.Val) - prev.Right = root - root = root.Left - } else { - prev.Right = nil - root = root.Right - } +func preorderTraversal(root *TreeNode) (ans []int) { + var dfs func(*TreeNode) + dfs = func(root *TreeNode) { + if root == nil { + return } + ans = append(ans, root.Val) + dfs(root.Left) + dfs(root.Right) } - return ans + dfs(root) + return } ``` @@ -212,15 +194,16 @@ func preorderTraversal(root *TreeNode) []int { */ function preorderTraversal(root: TreeNode | null): number[] { - let ans = []; - if (!root) return ans; - let stk = [root]; - while (stk.length) { - let node = stk.pop(); - ans.push(node.val); - if (node.right) stk.push(node.right); - if (node.left) stk.push(node.left); - } + const ans: number[] = []; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; + } + ans.push(root.val); + dfs(root.left); + dfs(root.right); + }; + dfs(root); return ans; } ``` @@ -247,27 +230,38 @@ function preorderTraversal(root: TreeNode | null): number[] { use std::rc::Rc; use std::cell::RefCell; impl Solution { - fn dfs(root: &Option>>, res: &mut Vec) { + fn dfs(root: &Option>>, ans: &mut Vec) { if root.is_none() { return; } let node = root.as_ref().unwrap().borrow(); - res.push(node.val); - Self::dfs(&node.left, res); - Self::dfs(&node.right, res); + ans.push(node.val); + Self::dfs(&node.left, ans); + Self::dfs(&node.right, ans); } pub fn preorder_traversal(root: Option>>) -> Vec { - let mut res = vec![]; - Self::dfs(&root, &mut res); - res + let mut ans = vec![]; + Self::dfs(&root, &mut ans); + ans } } ``` -### 方法二 +### 方法二:栈实现非递归遍历 + +栈实现非递归遍历的思路如下: + +1. 定义一个栈 $stk$,先将根节点压入栈 +1. 若栈不为空,每次从栈中弹出一个节点 +1. 处理该节点 +1. 先把节点右孩子压入栈,接着把节点左孩子压入栈(如果有孩子节点) +1. 重复 2-4 +1. 返回结果 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树的节点数,空间复杂度主要取决于栈空间。 @@ -333,6 +327,72 @@ class Solution { } ``` +```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) {} + * }; + */ +class Solution { +public: + vector preorderTraversal(TreeNode* root) { + vector ans; + if (!root) { + return ans; + } + stack stk; + stk.push(root); + while (stk.size()) { + auto node = stk.top(); + stk.pop(); + ans.push_back(node->val); + if (node->right) { + stk.push(node->right); + } + if (node->left) { + stk.push(node->left); + } + } + return ans; + } +}; +``` + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func preorderTraversal(root *TreeNode) (ans []int) { + if root == nil { + return + } + stk := []*TreeNode{root} + for len(stk) > 0 { + node := stk[len(stk)-1] + stk = stk[:len(stk)-1] + ans = append(ans, node.Val) + if node.Right != nil { + stk = append(stk, node.Right) + } + if node.Left != nil { + stk = append(stk, node.Left) + } + } + return +} +``` + ```ts /** * Definition for a binary tree node. @@ -349,77 +409,36 @@ class Solution { */ function preorderTraversal(root: TreeNode | null): number[] { - let ans = []; - while (root) { - if (!root.left) { - ans.push(root.val); - root = root.right; - } else { - let prev = root.left; - while (prev.right && prev.right != root) { - prev = prev.right; - } - if (!prev.right) { - ans.push(root.val); - prev.right = root; - root = root.left; - } else { - prev.right = null; - root = root.right; - } - } + const ans: number[] = []; + if (!root) { + return ans; } - return ans; -} -``` - -```rust -// Definition for a binary tree node. -// #[derive(Debug, PartialEq, Eq)] -// pub struct TreeNode { -// pub val: i32, -// pub left: Option>>, -// pub right: Option>>, -// } -// -// impl TreeNode { -// #[inline] -// pub fn new(val: i32) -> Self { -// TreeNode { -// val, -// left: None, -// right: None -// } -// } -// } -use std::rc::Rc; -use std::cell::RefCell; -impl Solution { - pub fn preorder_traversal(mut root: Option>>) -> Vec { - let mut res = vec![]; - if root.is_none() { - return res; - } - let mut stack = vec![]; - while root.is_some() || stack.len() != 0 { - if root.is_some() { - let val = root.as_ref().unwrap().as_ref().borrow().val; - let left = root.as_ref().unwrap().as_ref().borrow_mut().left.take(); - res.push(val); - stack.push(root); - root = left; - } else { - root = stack.pop().unwrap().as_ref().unwrap().as_ref().borrow_mut().right.take(); - } - } - res + const stk: TreeNode[] = [root]; + while (stk.length) { + const { left, right, val } = stk.pop(); + ans.push(val); + right && stk.push(right); + left && stk.push(left); } + return ans; } ``` -### 方法三 +### 方法三:Morris 实现前序遍历 + +Morris 遍历无需使用栈,空间复杂度为 $O(1)$。核心思想是: + +遍历二叉树节点, + +1. 若当前节点 `root` 的左子树为空,将当前节点值添加至结果列表 $ans$ 中,并将当前节点更新为 `root.right` +1. 若当前节点 `root` 的左子树不为空,找到左子树的最右节点 `pre`(也即是 `root` 节点在中序遍历下的前驱节点): + - 若前驱节点 `pre` 的右子树为空,将当前节点值添加至结果列表 $ans$ 中,然后将前驱节点的右子树指向当前节点 `root`,并将当前节点更新为 `root.left`。 + - 若前驱节点 `pre` 的右子树不为空,将前驱节点右子树指向空(即解除 `pre` 与 `root` 的指向关系),并将当前节点更新为 `root.right`。 +1. 循环以上步骤,直至二叉树节点为空,遍历结束。 + +时间复杂度 $O(n)$,其中 $n$ 是二叉树的节点数。空间复杂度 $O(1)$。 @@ -494,6 +513,120 @@ class Solution { } ``` +```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) {} + * }; + */ +class Solution { +public: + vector preorderTraversal(TreeNode* root) { + vector ans; + while (root) { + if (!root->left) { + ans.push_back(root->val); + root = root->right; + } else { + TreeNode* prev = root->left; + while (prev->right && prev->right != root) { + prev = prev->right; + } + if (!prev->right) { + ans.push_back(root->val); + prev->right = root; + root = root->left; + } else { + prev->right = nullptr; + root = root->right; + } + } + } + return ans; + } +}; +``` + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func preorderTraversal(root *TreeNode) (ans []int) { + for root != nil { + if root.Left == nil { + ans = append(ans, root.Val) + root = root.Right + } else { + prev := root.Left + for prev.Right != nil && prev.Right != root { + prev = prev.Right + } + if prev.Right == nil { + ans = append(ans, root.Val) + prev.Right = root + root = root.Left + } else { + prev.Right = nil + root = root.Right + } + } + } + return +} +``` + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function preorderTraversal(root: TreeNode | null): number[] { + const ans: number[] = []; + while (root) { + const { left, right, val } = root; + if (!left) { + ans.push(val); + root = right; + } else { + let prev = left; + while (prev.right && prev.right != root) { + prev = prev.right; + } + if (!prev.right) { + ans.push(val); + prev.right = root; + root = root.left; + } else { + prev.right = null; + root = root.right; + } + } + } + return ans; +} +``` + diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/README_EN.md b/solution/0100-0199/0144.Binary Tree Preorder Traversal/README_EN.md index 92403e6a88f7c..8a974ab2f327a 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/README_EN.md +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/README_EN.md @@ -41,7 +41,11 @@ ## Solutions -### Solution 1 +### Solution 1: Recursive Traversal + +We first visit the root node, then recursively traverse the left and right subtrees. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree. The space complexity mainly depends on the stack space used for recursive calls. @@ -57,7 +61,6 @@ class Solution: def dfs(root): if root is None: return - nonlocal ans ans.append(root.val) dfs(root.left) dfs(root.right) @@ -84,10 +87,9 @@ class Solution: * } */ class Solution { - private List ans; + private List ans = new ArrayList<>(); public List preorderTraversal(TreeNode root) { - ans = new ArrayList<>(); dfs(root); return ans; } @@ -119,25 +121,15 @@ class Solution { public: vector preorderTraversal(TreeNode* root) { vector ans; - while (root) { - if (!root->left) { - ans.push_back(root->val); - root = root->right; - } else { - TreeNode* prev = root->left; - while (prev->right && prev->right != root) { - prev = prev->right; - } - if (!prev->right) { - ans.push_back(root->val); - prev->right = root; - root = root->left; - } else { - prev->right = nullptr; - root = root->right; - } + function dfs = [&](TreeNode* root) { + if (!root) { + return; } - } + ans.push_back(root->val); + dfs(root->left); + dfs(root->right); + }; + dfs(root); return ans; } }; @@ -152,28 +144,18 @@ public: * Right *TreeNode * } */ -func preorderTraversal(root *TreeNode) []int { - var ans []int - for root != nil { - if root.Left == nil { - ans = append(ans, root.Val) - root = root.Right - } else { - prev := root.Left - for prev.Right != nil && prev.Right != root { - prev = prev.Right - } - if prev.Right == nil { - ans = append(ans, root.Val) - prev.Right = root - root = root.Left - } else { - prev.Right = nil - root = root.Right - } +func preorderTraversal(root *TreeNode) (ans []int) { + var dfs func(*TreeNode) + dfs = func(root *TreeNode) { + if root == nil { + return } + ans = append(ans, root.Val) + dfs(root.Left) + dfs(root.Right) } - return ans + dfs(root) + return } ``` @@ -193,15 +175,16 @@ func preorderTraversal(root *TreeNode) []int { */ function preorderTraversal(root: TreeNode | null): number[] { - let ans = []; - if (!root) return ans; - let stk = [root]; - while (stk.length) { - let node = stk.pop(); - ans.push(node.val); - if (node.right) stk.push(node.right); - if (node.left) stk.push(node.left); - } + const ans: number[] = []; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; + } + ans.push(root.val); + dfs(root.left); + dfs(root.right); + }; + dfs(root); return ans; } ``` @@ -228,27 +211,38 @@ function preorderTraversal(root: TreeNode | null): number[] { use std::rc::Rc; use std::cell::RefCell; impl Solution { - fn dfs(root: &Option>>, res: &mut Vec) { + fn dfs(root: &Option>>, ans: &mut Vec) { if root.is_none() { return; } let node = root.as_ref().unwrap().borrow(); - res.push(node.val); - Self::dfs(&node.left, res); - Self::dfs(&node.right, res); + ans.push(node.val); + Self::dfs(&node.left, ans); + Self::dfs(&node.right, ans); } pub fn preorder_traversal(root: Option>>) -> Vec { - let mut res = vec![]; - Self::dfs(&root, &mut res); - res + let mut ans = vec![]; + Self::dfs(&root, &mut ans); + ans } } ``` -### Solution 2 +### Solution 2: Stack Implementation for Non-Recursive Traversal + +The idea of using a stack to implement non-recursive traversal is as follows: + +1. Define a stack $stk$, and first push the root node into the stack. +2. If the stack is not empty, pop a node from the stack each time. +3. Process the node. +4. First push the right child of the node into the stack, then push the left child of the node into the stack (if there are child nodes). +5. Repeat steps 2-4. +6. Return the result. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree. The space complexity mainly depends on the stack space. @@ -314,6 +308,72 @@ class Solution { } ``` +```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) {} + * }; + */ +class Solution { +public: + vector preorderTraversal(TreeNode* root) { + vector ans; + if (!root) { + return ans; + } + stack stk; + stk.push(root); + while (stk.size()) { + auto node = stk.top(); + stk.pop(); + ans.push_back(node->val); + if (node->right) { + stk.push(node->right); + } + if (node->left) { + stk.push(node->left); + } + } + return ans; + } +}; +``` + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func preorderTraversal(root *TreeNode) (ans []int) { + if root == nil { + return + } + stk := []*TreeNode{root} + for len(stk) > 0 { + node := stk[len(stk)-1] + stk = stk[:len(stk)-1] + ans = append(ans, node.Val) + if node.Right != nil { + stk = append(stk, node.Right) + } + if node.Left != nil { + stk = append(stk, node.Left) + } + } + return +} +``` + ```ts /** * Definition for a binary tree node. @@ -330,77 +390,36 @@ class Solution { */ function preorderTraversal(root: TreeNode | null): number[] { - let ans = []; - while (root) { - if (!root.left) { - ans.push(root.val); - root = root.right; - } else { - let prev = root.left; - while (prev.right && prev.right != root) { - prev = prev.right; - } - if (!prev.right) { - ans.push(root.val); - prev.right = root; - root = root.left; - } else { - prev.right = null; - root = root.right; - } - } + const ans: number[] = []; + if (!root) { + return ans; } - return ans; -} -``` - -```rust -// Definition for a binary tree node. -// #[derive(Debug, PartialEq, Eq)] -// pub struct TreeNode { -// pub val: i32, -// pub left: Option>>, -// pub right: Option>>, -// } -// -// impl TreeNode { -// #[inline] -// pub fn new(val: i32) -> Self { -// TreeNode { -// val, -// left: None, -// right: None -// } -// } -// } -use std::rc::Rc; -use std::cell::RefCell; -impl Solution { - pub fn preorder_traversal(mut root: Option>>) -> Vec { - let mut res = vec![]; - if root.is_none() { - return res; - } - let mut stack = vec![]; - while root.is_some() || stack.len() != 0 { - if root.is_some() { - let val = root.as_ref().unwrap().as_ref().borrow().val; - let left = root.as_ref().unwrap().as_ref().borrow_mut().left.take(); - res.push(val); - stack.push(root); - root = left; - } else { - root = stack.pop().unwrap().as_ref().unwrap().as_ref().borrow_mut().right.take(); - } - } - res + const stk: TreeNode[] = [root]; + while (stk.length) { + const { left, right, val } = stk.pop(); + ans.push(val); + right && stk.push(right); + left && stk.push(left); } + return ans; } ``` -### Solution 3 +### Solution 3: Morris Preorder Traversal + +Morris traversal does not require a stack, and its space complexity is $O(1)$. The core idea is: + +Traverse the binary tree nodes, + +1. If the left subtree of the current node `root` is empty, add the current node value to the result list $ans$, and update the current node to `root.right`. +1. If the left subtree of the current node `root` is not empty, find the rightmost node `pre` of the left subtree (which is the predecessor of the `root` node in inorder traversal): + - If the right subtree of the predecessor node `pre` is empty, add the current node value to the result list $ans$, then point the right subtree of the predecessor node to the current node `root`, and update the current node to `root.left`. + - If the right subtree of the predecessor node `pre` is not empty, point the right subtree of the predecessor node to null (i.e., disconnect `pre` and `root`), and update the current node to `root.right`. +1. Repeat the above steps until the binary tree node is null, and the traversal ends. + +The time complexity is $O(n)$, where $n$ is the number of nodes in the binary tree. The space complexity is $O(1)$. @@ -475,6 +494,120 @@ class Solution { } ``` +```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) {} + * }; + */ +class Solution { +public: + vector preorderTraversal(TreeNode* root) { + vector ans; + while (root) { + if (!root->left) { + ans.push_back(root->val); + root = root->right; + } else { + TreeNode* prev = root->left; + while (prev->right && prev->right != root) { + prev = prev->right; + } + if (!prev->right) { + ans.push_back(root->val); + prev->right = root; + root = root->left; + } else { + prev->right = nullptr; + root = root->right; + } + } + } + return ans; + } +}; +``` + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func preorderTraversal(root *TreeNode) (ans []int) { + for root != nil { + if root.Left == nil { + ans = append(ans, root.Val) + root = root.Right + } else { + prev := root.Left + for prev.Right != nil && prev.Right != root { + prev = prev.Right + } + if prev.Right == nil { + ans = append(ans, root.Val) + prev.Right = root + root = root.Left + } else { + prev.Right = nil + root = root.Right + } + } + } + return +} +``` + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function preorderTraversal(root: TreeNode | null): number[] { + const ans: number[] = []; + while (root) { + const { left, right, val } = root; + if (!left) { + ans.push(val); + root = right; + } else { + let prev = left; + while (prev.right && prev.right != root) { + prev = prev.right; + } + if (!prev.right) { + ans.push(val); + prev.right = root; + root = root.left; + } else { + prev.right = null; + root = root.right; + } + } + } + return ans; +} +``` + diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.cpp b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.cpp index e5d4e3e0adaa3..315453a9610f7 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.cpp +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.cpp @@ -13,25 +13,15 @@ class Solution { public: vector preorderTraversal(TreeNode* root) { vector ans; - while (root) { - if (!root->left) { - ans.push_back(root->val); - root = root->right; - } else { - TreeNode* prev = root->left; - while (prev->right && prev->right != root) { - prev = prev->right; - } - if (!prev->right) { - ans.push_back(root->val); - prev->right = root; - root = root->left; - } else { - prev->right = nullptr; - root = root->right; - } + function dfs = [&](TreeNode* root) { + if (!root) { + return; } - } + ans.push_back(root->val); + dfs(root->left); + dfs(root->right); + }; + dfs(root); return ans; } }; \ No newline at end of file diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.go b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.go index d5e2a39b01d62..29d59c252d3c4 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.go +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.go @@ -6,26 +6,16 @@ * Right *TreeNode * } */ -func preorderTraversal(root *TreeNode) []int { - var ans []int - for root != nil { - if root.Left == nil { - ans = append(ans, root.Val) - root = root.Right - } else { - prev := root.Left - for prev.Right != nil && prev.Right != root { - prev = prev.Right - } - if prev.Right == nil { - ans = append(ans, root.Val) - prev.Right = root - root = root.Left - } else { - prev.Right = nil - root = root.Right - } +func preorderTraversal(root *TreeNode) (ans []int) { + var dfs func(*TreeNode) + dfs = func(root *TreeNode) { + if root == nil { + return } + ans = append(ans, root.Val) + dfs(root.Left) + dfs(root.Right) } - return ans + dfs(root) + return } \ No newline at end of file diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.java b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.java index 7d90054c94d98..a2a2b632f03b4 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.java +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.java @@ -14,10 +14,9 @@ * } */ class Solution { - private List ans; + private List ans = new ArrayList<>(); public List preorderTraversal(TreeNode root) { - ans = new ArrayList<>(); dfs(root); return ans; } diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.py b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.py index 39938612939ae..b89e90ad03735 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.py +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.py @@ -9,7 +9,6 @@ def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: def dfs(root): if root is None: return - nonlocal ans ans.append(root.val) dfs(root.left) dfs(root.right) diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.rs b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.rs index d95d0b0870019..10a576ba529d2 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.rs +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.rs @@ -19,19 +19,19 @@ use std::rc::Rc; use std::cell::RefCell; impl Solution { - fn dfs(root: &Option>>, res: &mut Vec) { + fn dfs(root: &Option>>, ans: &mut Vec) { if root.is_none() { return; } let node = root.as_ref().unwrap().borrow(); - res.push(node.val); - Self::dfs(&node.left, res); - Self::dfs(&node.right, res); + ans.push(node.val); + Self::dfs(&node.left, ans); + Self::dfs(&node.right, ans); } pub fn preorder_traversal(root: Option>>) -> Vec { - let mut res = vec![]; - Self::dfs(&root, &mut res); - res + let mut ans = vec![]; + Self::dfs(&root, &mut ans); + ans } } diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.ts b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.ts index 9e3ee928fba45..2359cc4503902 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.ts +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution.ts @@ -13,14 +13,15 @@ */ function preorderTraversal(root: TreeNode | null): number[] { - let ans = []; - if (!root) return ans; - let stk = [root]; - while (stk.length) { - let node = stk.pop(); - ans.push(node.val); - if (node.right) stk.push(node.right); - if (node.left) stk.push(node.left); - } + const ans: number[] = []; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; + } + ans.push(root.val); + dfs(root.left); + dfs(root.right); + }; + dfs(root); return ans; } diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.cpp b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.cpp new file mode 100644 index 0000000000000..00e6e86494fd9 --- /dev/null +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.cpp @@ -0,0 +1,34 @@ +/** + * 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 preorderTraversal(TreeNode* root) { + vector ans; + if (!root) { + return ans; + } + stack stk; + stk.push(root); + while (stk.size()) { + auto node = stk.top(); + stk.pop(); + ans.push_back(node->val); + if (node->right) { + stk.push(node->right); + } + if (node->left) { + stk.push(node->left); + } + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.go b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.go new file mode 100644 index 0000000000000..c1b06a79332b4 --- /dev/null +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.go @@ -0,0 +1,26 @@ +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func preorderTraversal(root *TreeNode) (ans []int) { + if root == nil { + return + } + stk := []*TreeNode{root} + for len(stk) > 0 { + node := stk[len(stk)-1] + stk = stk[:len(stk)-1] + ans = append(ans, node.Val) + if node.Right != nil { + stk = append(stk, node.Right) + } + if node.Left != nil { + stk = append(stk, node.Left) + } + } + return +} \ No newline at end of file diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.rs b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.rs deleted file mode 100644 index b91f1e2f9e075..0000000000000 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Definition for a binary tree node. -// #[derive(Debug, PartialEq, Eq)] -// pub struct TreeNode { -// pub val: i32, -// pub left: Option>>, -// pub right: Option>>, -// } -// -// impl TreeNode { -// #[inline] -// pub fn new(val: i32) -> Self { -// TreeNode { -// val, -// left: None, -// right: None -// } -// } -// } -use std::rc::Rc; -use std::cell::RefCell; -impl Solution { - pub fn preorder_traversal(mut root: Option>>) -> Vec { - let mut res = vec![]; - if root.is_none() { - return res; - } - let mut stack = vec![]; - while root.is_some() || stack.len() != 0 { - if root.is_some() { - let val = root.as_ref().unwrap().as_ref().borrow().val; - let left = root.as_ref().unwrap().as_ref().borrow_mut().left.take(); - res.push(val); - stack.push(root); - root = left; - } else { - root = stack.pop().unwrap().as_ref().unwrap().as_ref().borrow_mut().right.take(); - } - } - res - } -} diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.ts b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.ts index 1ddd5477c42e5..e2d0700b8eda5 100644 --- a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.ts +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution2.ts @@ -13,25 +13,16 @@ */ function preorderTraversal(root: TreeNode | null): number[] { - let ans = []; - while (root) { - if (!root.left) { - ans.push(root.val); - root = root.right; - } else { - let prev = root.left; - while (prev.right && prev.right != root) { - prev = prev.right; - } - if (!prev.right) { - ans.push(root.val); - prev.right = root; - root = root.left; - } else { - prev.right = null; - root = root.right; - } - } + const ans: number[] = []; + if (!root) { + return ans; + } + const stk: TreeNode[] = [root]; + while (stk.length) { + const { left, right, val } = stk.pop(); + ans.push(val); + right && stk.push(right); + left && stk.push(left); } return ans; } diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.cpp b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.cpp new file mode 100644 index 0000000000000..e5d4e3e0adaa3 --- /dev/null +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.cpp @@ -0,0 +1,37 @@ +/** + * 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 preorderTraversal(TreeNode* root) { + vector ans; + while (root) { + if (!root->left) { + ans.push_back(root->val); + root = root->right; + } else { + TreeNode* prev = root->left; + while (prev->right && prev->right != root) { + prev = prev->right; + } + if (!prev->right) { + ans.push_back(root->val); + prev->right = root; + root = root->left; + } else { + prev->right = nullptr; + root = root->right; + } + } + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.go b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.go new file mode 100644 index 0000000000000..7623c68998171 --- /dev/null +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.go @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func preorderTraversal(root *TreeNode) (ans []int) { + for root != nil { + if root.Left == nil { + ans = append(ans, root.Val) + root = root.Right + } else { + prev := root.Left + for prev.Right != nil && prev.Right != root { + prev = prev.Right + } + if prev.Right == nil { + ans = append(ans, root.Val) + prev.Right = root + root = root.Left + } else { + prev.Right = nil + root = root.Right + } + } + } + return +} \ No newline at end of file diff --git a/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.ts b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.ts new file mode 100644 index 0000000000000..a28756c83bde7 --- /dev/null +++ b/solution/0100-0199/0144.Binary Tree Preorder Traversal/Solution3.ts @@ -0,0 +1,38 @@ +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function preorderTraversal(root: TreeNode | null): number[] { + const ans: number[] = []; + while (root) { + const { left, right, val } = root; + if (!left) { + ans.push(val); + root = right; + } else { + let prev = left; + while (prev.right && prev.right != root) { + prev = prev.right; + } + if (!prev.right) { + ans.push(val); + prev.right = root; + root = root.left; + } else { + prev.right = null; + root = root.right; + } + } + } + return ans; +}