Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
552e24b
Update 0226.翻转二叉树.md
molonlu May 18, 2022
f389dcd
添加 二叉树理论基础.md Scala版本
wzqwtt May 18, 2022
b2be41e
添加 二叉树的递归遍历.md Scala版本
wzqwtt May 18, 2022
d6d227c
Update 0110.平衡二叉树.md
May 18, 2022
4aad0f9
添加 二叉树的迭代遍历.md Scala版本
wzqwtt May 18, 2022
54d10fc
添加(0300.最长上升子序列.md):增加typescript版本
xiaofei-2020 May 18, 2022
52a4861
添加(0674.最长连续递增序列.md):增加typescript版本
xiaofei-2020 May 18, 2022
648014b
添加 二叉树的统一迭代法.md Scala版本
wzqwtt May 19, 2022
33ed3d9
添加 102.二叉树的层序遍历 Scala版本
wzqwtt May 19, 2022
0433956
添加 107.二叉树的层次遍历II Scala版本
wzqwtt May 19, 2022
ba51a49
添加 199.二叉树的右视图 Scala版本
wzqwtt May 19, 2022
9af80d3
添加 637.二叉树的层平均值 Scala版本
wzqwtt May 19, 2022
c922fbc
添加 429.N叉树的层序遍历 Scala版本
wzqwtt May 19, 2022
c85105c
Merge pull request #1345 from molonlu/patch-1
youngyangyang04 Jun 10, 2022
0bb5277
Merge pull request #1346 from areslk/areslk-patch-1
youngyangyang04 Jun 10, 2022
1ef962f
Merge pull request #1348 from wzqwtt/tree01
youngyangyang04 Jun 10, 2022
d00168d
Merge pull request #1349 from xiaofei-2020/dp41
youngyangyang04 Jun 10, 2022
da137a1
Merge pull request #1350 from xiaofei-2020/dp42
youngyangyang04 Jun 10, 2022
edbb487
Merge branch 'master' into tree02
youngyangyang04 Jun 10, 2022
71865c1
Merge pull request #1351 from wzqwtt/tree02
youngyangyang04 Jun 10, 2022
e4d638f
Merge pull request #1352 from wzqwtt/tree03
youngyangyang04 Jun 10, 2022
f5f5f5a
Update
youngyangyang04 Jun 10, 2022
af239ce
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
youngyangyang04 Jun 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions problems/0027.移除元素.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

## 思路

[本题B站视频讲解](https://www.bilibili.com/video/BV12A4y1Z7LP)

有的同学可能说了,多余的元素,删掉不就得了。

**要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。**
Expand Down Expand Up @@ -75,10 +77,20 @@ public:

双指针法(快慢指针法): **通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。**

定义快慢指针

* 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
* 慢指针:指向更新 新数组下标的位置

很多同学这道题目做的很懵,就是不理解 快慢指针究竟都是什么含义,所以一定要明确含义,后面的思路就更容易理解了。

删除过程如下:

![27.移除元素-双指针法](https://tva1.sinaimg.cn/large/008eGmZEly1gntrds6r59g30du09mnpd.gif)

很多同学不了解


**双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法。**

后续都会一一介绍到,本题代码如下:
Expand All @@ -104,8 +116,6 @@ public:
* 时间复杂度:O(n)
* 空间复杂度:O(1)

旧文链接:[数组:就移除个元素很难么?](https://programmercarl.com/0027.移除元素.html)

```CPP
/**
* 相向双指针方法,基于元素顺序可以改变的题目描述改变了元素相对位置,确保了移动最少元素
Expand Down
12 changes: 6 additions & 6 deletions problems/0035.搜索插入位置.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ public:
};
```

* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$
* 时间复杂度:O(n)
* 空间复杂度:O(1)

效率如下:

Expand Down Expand Up @@ -135,14 +135,14 @@ public:
// 目标值在数组所有元素之前 [0, -1]
// 目标值等于数组中某一个元素 return middle;
// 目标值插入数组中的位置 [left, right],return right + 1
// 目标值在数组所有元素之后的情况 [left, right], return right + 1
// 目标值在数组所有元素之后的情况 [left, right], 因为是右闭区间,所以 return right + 1
return right + 1;
}
};
```

* 时间复杂度:$O(\log n)$
* 时间复杂度:$O(1)$
* 时间复杂度:O(log n)
* 时间复杂度:O(1)

效率如下:
![35_搜索插入位置2](https://img-blog.csdnimg.cn/2020121623272877.png)
Expand Down Expand Up @@ -178,7 +178,7 @@ public:
// 目标值在数组所有元素之前 [0,0)
// 目标值等于数组中某一个元素 return middle
// 目标值插入数组中的位置 [left, right) ,return right 即可
// 目标值在数组所有元素之后的情况 [left, right),return right 即可
// 目标值在数组所有元素之后的情况 [left, right),因为是右开区间,所以 return right
return right;
}
};
Expand Down
128 changes: 128 additions & 0 deletions problems/0102.二叉树的层序遍历.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,31 @@ func levelOrder(_ root: TreeNode?) -> [[Int]] {
return result
}
```
Scala:
```scala
// 102.二叉树的层序遍历
object Solution {
import scala.collection.mutable
def levelOrder(root: TreeNode): List[List[Int]] = {
val res = mutable.ListBuffer[List[Int]]()
if (root == null) return res.toList
val queue = mutable.Queue[TreeNode]() // 声明一个队列
queue.enqueue(root) // 把根节点加入queue
while (!queue.isEmpty) {
val tmp = mutable.ListBuffer[Int]()
val len = queue.size // 求出len的长度
for (i <- 0 until len) { // 从0到当前队列长度的所有节点都加入到结果集
val curNode = queue.dequeue()
tmp.append(curNode.value)
if (curNode.left != null) queue.enqueue(curNode.left)
if (curNode.right != null) queue.enqueue(curNode.right)
}
res.append(tmp.toList)
}
res.toList
}
}
```

Rust:

Expand Down Expand Up @@ -578,6 +603,32 @@ func levelOrderBottom(_ root: TreeNode?) -> [[Int]] {
}
```


Scala:
```scala
// 107.二叉树的层次遍历II
object Solution {
import scala.collection.mutable
def levelOrderBottom(root: TreeNode): List[List[Int]] = {
val res = mutable.ListBuffer[List[Int]]()
if (root == null) return res.toList
val queue = mutable.Queue[TreeNode]()
queue.enqueue(root)
while (!queue.isEmpty) {
val tmp = mutable.ListBuffer[Int]()
val len = queue.size
for (i <- 0 until len) {
val curNode = queue.dequeue()
tmp.append(curNode.value)
if (curNode.left != null) queue.enqueue(curNode.left)
if (curNode.right != null) queue.enqueue(curNode.right)
}
res.append(tmp.toList)
}
// 最后翻转一下
res.reverse.toList
}

Rust:

```rust
Expand Down Expand Up @@ -829,6 +880,31 @@ func rightSideView(_ root: TreeNode?) -> [Int] {
}
```

Scala:
```scala
// 199.二叉树的右视图
object Solution {
import scala.collection.mutable
def rightSideView(root: TreeNode): List[Int] = {
val res = mutable.ListBuffer[Int]()
if (root == null) return res.toList
val queue = mutable.Queue[TreeNode]()
queue.enqueue(root)
while (!queue.isEmpty) {
val len = queue.size
var curNode: TreeNode = null
for (i <- 0 until len) {
curNode = queue.dequeue()
if (curNode.left != null) queue.enqueue(curNode.left)
if (curNode.right != null) queue.enqueue(curNode.right)
}
res.append(curNode.value) // 把最后一个节点的值加入解集
}
res.toList // 最后需要把res转换为List,return关键字可以省略
}
}
```

# 637.二叉树的层平均值

[力扣题目链接](https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/)
Expand Down Expand Up @@ -1060,6 +1136,30 @@ func averageOfLevels(_ root: TreeNode?) -> [Double] {
return result
}
```
Scala:
```scala
// 637.二叉树的层平均值
object Solution {
import scala.collection.mutable
def averageOfLevels(root: TreeNode): Array[Double] = {
val res = mutable.ArrayBuffer[Double]()
val queue = mutable.Queue[TreeNode]()
queue.enqueue(root)
while (!queue.isEmpty) {
var sum = 0.0
var len = queue.size
for (i <- 0 until len) {
var curNode = queue.dequeue()
sum += curNode.value // 累加该层的值
if (curNode.left != null) queue.enqueue(curNode.left)
if (curNode.right != null) queue.enqueue(curNode.right)
}
res.append(sum / len) // 平均值即为sum/len
}
res.toArray // 最后需要转换为Array,return关键字可以省略
}
}
```

# 429.N叉树的层序遍历

Expand Down Expand Up @@ -1304,6 +1404,34 @@ func levelOrder(_ root: Node?) -> [[Int]] {
}
```

Scala:
```scala
// 429.N叉树的层序遍历
object Solution {
import scala.collection.mutable
def levelOrder(root: Node): List[List[Int]] = {
val res = mutable.ListBuffer[List[Int]]()
if (root == null) return res.toList
val queue = mutable.Queue[Node]()
queue.enqueue(root) // 根节点入队
while (!queue.isEmpty) {
val tmp = mutable.ListBuffer[Int]() // 存储每层节点
val len = queue.size
for (i <- 0 until len) {
val curNode = queue.dequeue()
tmp.append(curNode.value) // 将该节点的值加入tmp
// 循环遍历该节点的子节点,加入队列
for (child <- curNode.children) {
queue.enqueue(child)
}
}
res.append(tmp.toList) // 将该层的节点放到结果集
}
res.toList
}
}
```

# 515.在每个树行中找最大值

[力扣题目链接](https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/)
Expand Down
2 changes: 1 addition & 1 deletion problems/0110.平衡二叉树.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ int getHeight(TreeNode* node) {
```CPP
class Solution {
public:
// 返回以该节点为根节点的二叉树的高度,如果不是二叉搜索树了则返回-1
// 返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树了则返回-1
int getHeight(TreeNode* node) {
if (node == NULL) {
return 0;
Expand Down
4 changes: 1 addition & 3 deletions problems/0226.翻转二叉树.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,7 @@ func invertTree(root *TreeNode) *TreeNode {
if root ==nil{
return nil
}
temp:=root.Left
root.Left=root.Right
root.Right=temp
root.Left,root.Right=root.Right,root.Left//交换

invertTree(root.Left)
invertTree(root.Right)
Expand Down
21 changes: 21 additions & 0 deletions problems/0300.最长上升子序列.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,27 @@ const lengthOfLIS = (nums) => {
};
```

TypeScript

```typescript
function lengthOfLIS(nums: number[]): number {
/**
dp[i]: 前i个元素中,以nums[i]结尾,最长子序列的长度
*/
const dp: number[] = new Array(nums.length).fill(1);
let resMax: number = 0;
for (let i = 0, length = nums.length; i < length; i++) {
for (let j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
resMax = Math.max(resMax, dp[i]);
}
return resMax;
};
```




Expand Down
39 changes: 39 additions & 0 deletions problems/0674.最长连续递增序列.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,45 @@ const findLengthOfLCIS = (nums) => {
};
```

TypeScript:

> 动态规划:

```typescript
function findLengthOfLCIS(nums: number[]): number {
/**
dp[i]: 前i个元素,以nums[i]结尾,最长连续子序列的长度
*/
const dp: number[] = new Array(nums.length).fill(1);
let resMax: number = 1;
for (let i = 1, length = nums.length; i < length; i++) {
if (nums[i] > nums[i - 1]) {
dp[i] = dp[i - 1] + 1;
}
resMax = Math.max(resMax, dp[i]);
}
return resMax;
};
```

> 贪心:

```typescript
function findLengthOfLCIS(nums: number[]): number {
let resMax: number = 1;
let count: number = 1;
for (let i = 0, length = nums.length; i < length - 1; i++) {
if (nums[i] < nums[i + 1]) {
count++;
} else {
count = 1;
}
resMax = Math.max(resMax, count);
}
return resMax;
};
```




Expand Down
2 changes: 2 additions & 0 deletions problems/0704.二分查找.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

## 思路

为了易于大家理解,我还录制了视频,可以看这里:[手把手带你撕出正确的二分法](https://www.bilibili.com/video/BV1fA4y1o715)

**这道题目的前提是数组为有序数组**,同时题目还强调**数组中无重复元素**,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。

二分查找涉及的很多的边界条件,逻辑比较简单,但就是写不好。例如到底是 `while(left < right)` 还是 `while(left <= right)`,到底是`right = middle`呢,还是要`right = middle - 1`呢?
Expand Down
2 changes: 2 additions & 0 deletions problems/0977.有序数组的平方.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

# 思路

为了易于大家理解,我还特意录制了视频,[本题视频讲解](https://www.bilibili.com/video/BV1QB4y1D7ep)

## 暴力排序

最直观的想法,莫过于:每个数平方之后,排个序,美滋滋,代码如下:
Expand Down
Loading