Merge pull request #1109 from bqlin/master

优化排版与 Swift 实现
This commit is contained in:
程序员Carl
2022-03-13 10:44:05 +08:00
committed by GitHub
4 changed files with 258 additions and 247 deletions

View File

@ -273,32 +273,29 @@ function levelOrder(root: TreeNode | null): number[][] {
};
```
Swift:
Swift
```swift
func levelOrder(_ root: TreeNode?) -> [[Int]] {
var res = [[Int]]()
guard let root = root else {
return res
}
var queue = [TreeNode]()
queue.append(root)
var result = [[Int]]()
guard let root = root else { return result }
// 表示一层
var queue = [root]
while !queue.isEmpty {
let size = queue.count
var sub = [Int]()
for _ in 0 ..< size {
let count = queue.count
var subarray = [Int]()
for _ in 0 ..< count {
// 当前层
let node = queue.removeFirst()
sub.append(node.val)
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
}
subarray.append(node.val)
// 下一层
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node) }
}
res.append(sub)
result.append(subarray)
}
return res
return result
}
```
@ -505,30 +502,29 @@ function levelOrderBottom(root: TreeNode | null): number[][] {
};
```
Swift:
Swift
```swift
func levelOrderBottom(_ root: TreeNode?) -> [[Int]] {
var res = [[Int]]()
guard let root = root else {
return res
}
var queue: [TreeNode] = [root]
// 表示一层
var queue = [TreeNode]()
if let node = root { queue.append(node) }
var result = [[Int]]()
while !queue.isEmpty {
var sub = [Int]()
for _ in 0 ..< queue.count {
let count = queue.count
var subarray = [Int]()
for _ in 0 ..< count {
// 当前层
let node = queue.removeFirst()
sub.append(node.val)
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
}
subarray.append(node.val)
// 下一层
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node)}
}
res.insert(sub, at: 0)
result.append(subarray)
}
return res
return result.reversed()
}
```
@ -729,37 +725,31 @@ function rightSideView(root: TreeNode | null): number[] {
};
```
Swift:
Swift
```swift
func rightSideView(_ root: TreeNode?) -> [Int] {
var res = [Int]()
guard let root = root else {
return res
}
// 表示一层
var queue = [TreeNode]()
queue.append(root)
if let node = root { queue.append(node) }
var result = [Int]()
while !queue.isEmpty {
let size = queue.count
for i in 0 ..< size {
let count = queue.count
for i in 0 ..< count {
// 当前层
let node = queue.removeFirst()
if i == size - 1 {
// 保存 每层最后一个元素
res.append(node.val)
}
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
}
if i == count - 1 { result.append(node.val) }
// 下一层
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node) }
}
}
return res
return result
}
```
# 637.二叉树的层平均值
[力扣题目链接](https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/)
@ -965,32 +955,30 @@ function averageOfLevels(root: TreeNode | null): number[] {
};
```
Swift:
Swift
```swift
func averageOfLevels(_ root: TreeNode?) -> [Double] {
var res = [Double]()
guard let root = root else {
return res
}
// 表示一层
var queue = [TreeNode]()
queue.append(root)
if let node = root { queue.append(node) }
var result = [Double]()
while !queue.isEmpty {
let size = queue.count
let count = queue.count
var sum = 0
for _ in 0 ..< size {
for _ in 0 ..< count {
// 当前层
let node = queue.removeFirst()
sum += node.val
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
}
// 下一层
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node) }
}
res.append(Double(sum) / Double(size))
result.append(Double(sum) / Double(count))
}
return res
return result
}
```
@ -1212,29 +1200,28 @@ function levelOrder(root: Node | null): number[][] {
};
```
Swift:
Swift
```swift
func levelOrder(_ root: Node?) -> [[Int]] {
var res = [[Int]]()
guard let root = root else {
return res
}
// 表示一层
var queue = [Node]()
queue.append(root)
if let node = root { queue.append(node) }
var result = [[Int]]()
while !queue.isEmpty {
let size = queue.count
var sub = [Int]()
for _ in 0 ..< size {
let count = queue.count
var subarray = [Int]()
for _ in 0 ..< count {
// 当前层
let node = queue.removeFirst()
sub.append(node.val)
for childNode in node.children {
queue.append(childNode)
}
subarray.append(node.val)
// 下一层
for node in node.children { queue.append(node) }
}
res.append(sub)
result.append(subarray)
}
return res
return result
}
```
@ -1419,34 +1406,30 @@ function largestValues(root: TreeNode | null): number[] {
};
```
Swift:
Swift
```swift
func largestValues(_ root: TreeNode?) -> [Int] {
var res = [Int]()
guard let root = root else {
return res
}
// 表示一层
var queue = [TreeNode]()
queue.append(root)
if let node = root { queue.append(node) }
var result = [Int]()
while !queue.isEmpty {
let size = queue.count
var max: Int = Int.min
for _ in 0 ..< size {
let count = queue.count
var max = queue[0].val
for _ in 0 ..< count {
// 当前层
let node = queue.removeFirst()
if node.val > max {
max = node.val
}
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
}
if node.val > max { max = node.val }
// 下一层
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node) }
}
res.append(max)
result.append(max)
}
return res
return result
}
```
@ -1456,7 +1439,7 @@ func largestValues(_ root: TreeNode?) -> [Int] {
给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
```
```cpp
struct Node {
int val;
Node *left;
@ -1677,33 +1660,34 @@ func connect(root *Node) *Node {
}
```
Swift:
Swift
```swift
func connect(_ root: Node?) -> Node? {
guard let root = root else {
return nil
}
// 表示一层
var queue = [Node]()
queue.append(root)
if let node = root { queue.append(node) }
while !queue.isEmpty {
let size = queue.count
var preNode: Node?
for i in 0 ..< size {
let node = queue.removeFirst()
let count = queue.count
var current, previous: Node!
for i in 0 ..< count {
// 当前层
if i == 0 {
preNode = node
previous = queue.removeFirst()
current = previous
} else {
preNode?.next = node
preNode = node
}
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
current = queue.removeFirst()
previous.next = current
previous = current
}
// 下一层
if let node = current.left { queue.append(node) }
if let node = current.right { queue.append(node) }
}
previous.next = nil
}
return root
}
```
@ -1927,34 +1911,34 @@ func connect(root *Node) *Node {
return root
}
```
Swift
```swift
func connect(_ root: Node?) -> Node? {
guard let root = root else {
return nil
}
// 表示一层
var queue = [Node]()
queue.append(root)
if let node = root { queue.append(node) }
while !queue.isEmpty {
let size = queue.count
var preNode: Node?
for i in 0 ..< size {
let node = queue.removeFirst()
let count = queue.count
var current, previous: Node!
for i in 0 ..< count {
// 当前层
if i == 0 {
preNode = node
previous = queue.removeFirst()
current = previous
} else {
preNode?.next = node
preNode = node
}
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
current = queue.removeFirst()
previous.next = current
previous = current
}
// 下一层
if let node = current.left { queue.append(node) }
if let node = current.right { queue.append(node) }
}
previous.next = nil
}
return root
}
```
@ -2151,29 +2135,28 @@ function maxDepth(root: TreeNode | null): number {
};
```
Swift:
Swift
```swift
func maxDepth(_ root: TreeNode?) -> Int {
guard let root = root else {
return 0
}
guard root != nil else { return 0 }
var depth = 0
var queue = [TreeNode]()
queue.append(root)
var res: Int = 0
queue.append(root!)
while !queue.isEmpty {
for _ in 0 ..< queue.count {
let count = queue.count
depth += 1
for _ in 0 ..< count {
// 当前层
let node = queue.removeFirst()
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
}
// 下一层
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node) }
}
res += 1
}
return res
return depth
}
```
@ -2374,28 +2357,25 @@ Swift
```swift
func minDepth(_ root: TreeNode?) -> Int {
guard let root = root else {
return 0
}
var res = 0
var queue = [TreeNode]()
queue.append(root)
guard root != nil else { return 0 }
var depth = 0
var queue = [root!]
while !queue.isEmpty {
res += 1
for _ in 0 ..< queue.count {
let count = queue.count
depth += 1
for _ in 0 ..< count {
// 当前层
let node = queue.removeFirst()
if node.left == nil && node.right == nil {
return res
}
if let left = node.left {
queue.append(left)
}
if let right = node.right {
queue.append(right)
if node.left == nil, node.right == nil { // 遇到叶子结点则返回
return depth
}
// 下一层
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node) }
}
}
return res
return depth
}
```

View File

@ -47,8 +47,6 @@
## 递归法
对于二叉树的递归法的前中后序遍历,已经在[二叉树:前中后序递归遍历](https://programmercarl.com/二叉树的递归遍历.html)详细讲解了。
我们下文以前序遍历为例,通过动画来看一下翻转的过程:
@ -63,7 +61,7 @@
返回值的话其实也不需要但是题目中给出的要返回root节点的指针可以直接使用题目定义好的函数所以就函数的返回类型为`TreeNode*`
```
```cpp
TreeNode* invertTree(TreeNode* root)
```
@ -71,7 +69,7 @@ TreeNode* invertTree(TreeNode* root)
当前节点为空的时候,就返回
```
```cpp
if (root == NULL) return root;
```
@ -79,7 +77,7 @@ if (root == NULL) return root;
因为是先前序遍历,所以先进行交换左右孩子节点,然后反转左子树,反转右子树。
```
```cpp
swap(root->left, root->right);
invertTree(root->left);
invertTree(root->right);
@ -257,7 +255,7 @@ public:
## 其他语言版本
### Java
### Java
```Java
//DFS递归
@ -469,8 +467,6 @@ func invertTree(root *TreeNode) *TreeNode {
}
```
### JavaScript
使用递归版本的前序遍历
@ -690,7 +686,7 @@ function invertTree(root: TreeNode | null): TreeNode | null {
};
```
### C:
### C
递归法
```c
@ -775,5 +771,54 @@ func invertTree1(_ root: TreeNode?) -> TreeNode? {
}
```
### Swift
深度优先递归。
```swift
func invertTree(_ root: TreeNode?) -> TreeNode? {
guard let node = root else { return root }
swap(&node.left, &node.right)
_ = invertTree(node.left)
_ = invertTree(node.right)
return root
}
```
深度优先迭代,子结点顺序不重要,从根结点出发深度遍历即可。
```swift
func invertTree(_ root: TreeNode?) -> TreeNode? {
guard let node = root else { return root }
var stack = [node]
while !stack.isEmpty {
guard let node = stack.popLast() else { break }
swap(&node.left, &node.right)
if let node = node.left { stack.append(node) }
if let node = node.right { stack.append(node) }
}
return root
}
```
广度优先迭代。
```swift
func invertTree(_ root: TreeNode?) -> TreeNode? {
guard let node = root else { return root }
var queue = [node]
while !queue.isEmpty {
let count = queue.count
for _ in 0 ..< count {
let node = queue.removeFirst()
swap(&node.left, &node.right)
if let node = node.left { queue.append(node) }
if let node = node.right { queue.append(node) }
}
}
return root
}
```
-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>

View File

@ -390,7 +390,7 @@ func inorderTraversal(root *TreeNode) []int {
}
```
javaScript
javaScript
```js
@ -454,7 +454,7 @@ var postorderTraversal = function(root, res = []) {
};
```
TypeScript:
TypeScript
```typescript
// 前序遍历(迭代法)
@ -509,77 +509,63 @@ function postorderTraversal(root: TreeNode | null): number[] {
};
```
Swift:
Swift
> 迭代法前序遍历
```swift
// 前序遍历迭代法
func preorderTraversal(_ root: TreeNode?) -> [Int] {
var res = [Int]()
if root == nil {
return res
}
var stack = [TreeNode]()
stack.append(root!)
var result = [Int]()
guard let root = root else { return result }
var stack = [root]
while !stack.isEmpty {
let node = stack.popLast()!
res.append(node.val)
if node.right != nil {
stack.append(node.right!)
let current = stack.removeLast()
// 先右后左,这样出栈的时候才是左右顺序
if let node = current.right { // 右
stack.append(node)
}
if node.left != nil {
stack.append(node.left!)
if let node = current.left { // 左
stack.append(node)
}
result.append(current.val) // 中
}
return res
return result
}
```
> 迭代法中序遍历
```swift
func inorderTraversal(_ root: TreeNode?) -> [Int] {
var res = [Int]()
if root == nil {
return res
}
var stack = [TreeNode]()
var cur: TreeNode? = root
while cur != nil || !stack.isEmpty {
if cur != nil {
stack.append(cur!)
cur = cur!.left
} else {
cur = stack.popLast()
res.append(cur!.val)
cur = cur!.right
}
}
return res
}
```
> 迭代法后序遍历
```swift
// 后序遍历迭代法
func postorderTraversal(_ root: TreeNode?) -> [Int] {
var res = [Int]()
if root == nil {
return res
}
var stack = [TreeNode]()
stack.append(root!)
// res 存储 中 -> 右 -> 左
var result = [Int]()
guard let root = root else { return result }
var stack = [root]
while !stack.isEmpty {
let node = stack.popLast()!
res.append(node.val)
if node.left != nil {
stack.append(node.left!)
let current = stack.removeLast()
// 与前序相反,即中右左,最后结果还需反转才是后序
if let node = current.left { // 左
stack.append(node)
}
if node.right != nil {
stack.append(node.right!)
if let node = current.right { // 右
stack.append(node)
}
result.append(current.val) // 中
}
return result.reversed()
}
// 中序遍历迭代法
func inorderTraversal(_ root: TreeNode?) -> [Int] {
var result = [Int]()
var stack = [TreeNode]()
var current: TreeNode! = root
while current != nil || !stack.isEmpty {
if current != nil { // 先访问到最左叶子
stack.append(current)
current = current.left // 左
} else {
current = stack.removeLast()
result.append(current.val) // 中
current = current.right // 右
}
}
// res 翻转
res.reverse()
return res
return result
}
```

View File

@ -34,19 +34,19 @@
1. **确定递归函数的参数和返回值**因为要打印出前序遍历节点的数值所以参数里需要传入vector在放节点的数值除了这一点就不需要在处理什么数据了也不需要有返回值所以递归函数返回类型就是void代码如下
```
```cpp
void traversal(TreeNode* cur, vector<int>& vec)
```
2. **确定终止条件**在递归的过程中如何算是递归结束了呢当然是当前遍历的节点是空了那么本层递归就要要结束了所以如果当前遍历的这个节点是空就直接return代码如下
```
```cpp
if (cur == NULL) return;
```
3. **确定单层递归的逻辑**:前序遍历是中左右的循序,所以在单层递归的逻辑,是要先取中节点的数值,代码如下:
```
```cpp
vec.push_back(cur->val); // 中
traversal(cur->left, vec); // 左
traversal(cur->right, vec); // 右