mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 00:43:04 +08:00
Merge branch 'master' into master
This commit is contained in:
@ -393,6 +393,14 @@
|
||||
* [图论:1020.飞地的数量](./problems/1020.飞地的数量.md)
|
||||
* [图论:130.被围绕的区域](./problems/0130.被围绕的区域.md)
|
||||
* [图论:417.太平洋大西洋水流问题](./problems/0417.太平洋大西洋水流问题.md)
|
||||
* [图论:827.最大人工岛](./problems/0827.最大人工岛.md)
|
||||
* [图论:127. 单词接龙](./problems/0127.单词接龙.md)
|
||||
* [图论:841.钥匙和房间](./problems/841.钥匙和房间)
|
||||
* [图论:463. 岛屿的周长](./problems/0463.岛屿的周长.md)
|
||||
* [图论:并查集理论基础](./problems/)
|
||||
* [图论:1971. 寻找图中是否存在路径](./problems/1971.寻找图中是否存在路径.md)
|
||||
* [图论:684.冗余连接](./problems/0684.冗余连接.md)
|
||||
* [图论:685.冗余连接II](./problems/0685.冗余连接II.md)
|
||||
|
||||
(持续更新中....)
|
||||
|
||||
|
@ -739,6 +739,60 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### C
|
||||
```c
|
||||
int searchLeftBorder(int *nums, int numsSize, int target) {
|
||||
int left = 0, right = numsSize - 1;
|
||||
// 记录leftBorder没有被赋值的情况
|
||||
int leftBorder = -1;
|
||||
// 边界为[left, right]
|
||||
while (left <= right) {
|
||||
// 更新middle值,等同于middle = (left + right) / 2
|
||||
int middle = left + ((right - left) >> 1);
|
||||
// 若当前middle所指为target,将左边界设为middle,并向左继续寻找左边界
|
||||
if (nums[middle] == target) {
|
||||
leftBorder = middle;
|
||||
right = middle - 1;
|
||||
} else if (nums[middle] > target) {
|
||||
right = middle - 1;
|
||||
} else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
return leftBorder;
|
||||
}
|
||||
int searchRightBorder(int *nums, int numsSize, int target) {
|
||||
int left = 0, right = numsSize - 1;
|
||||
// 记录rightBorder没有被赋值的情况
|
||||
int rightBorder = -1;
|
||||
while (left <= right) {
|
||||
int middle = left + ((right - left) >> 1);
|
||||
// 若当前middle所指为target,将右边界设为middle,并向右继续寻找右边界
|
||||
if (nums[middle] == target) {
|
||||
rightBorder = middle;
|
||||
left = middle + 1;
|
||||
} else if (nums[middle] > target) {
|
||||
right = middle - 1;
|
||||
} else {
|
||||
left = middle + 1;
|
||||
}
|
||||
}
|
||||
return rightBorder;
|
||||
}
|
||||
|
||||
int* searchRange(int* nums, int numsSize, int target, int* returnSize){
|
||||
int leftBorder = searchLeftBorder(nums, numsSize, target);
|
||||
int rightBorder = searchRightBorder(nums, numsSize, target);
|
||||
|
||||
// 定义返回数组及数组大小
|
||||
*returnSize = 2;
|
||||
int *resNums = (int*)malloc(sizeof(int) * 2);
|
||||
resNums[0] = leftBorder;
|
||||
resNums[1] = rightBorder;
|
||||
return resNums;
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -41,7 +41,7 @@ exection -> execution (插入 'u')
|
||||
* word1 和 word2 由小写英文字母组成
|
||||
|
||||
## 算法公开课
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划终极绝杀! LeetCode:72.编辑距离](https://www.bilibili.com/video/BV1we4y157wB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划终极绝杀! LeetCode:72.编辑距离](https://www.bilibili.com/video/BV1qv4y1q78f/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
## 思路
|
||||
|
||||
@ -465,4 +465,3 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -764,6 +764,35 @@ object Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### Ruby
|
||||
|
||||
```ruby
|
||||
|
||||
def combine(n, k)
|
||||
result = []
|
||||
path = []
|
||||
backtracking(result, path, n, 1, k)
|
||||
return result
|
||||
end
|
||||
|
||||
#剪枝优化
|
||||
def backtracking(result, path, n, j, k)
|
||||
if path.size == k
|
||||
result << path.map {|item| item}
|
||||
return
|
||||
end
|
||||
|
||||
for i in j..(n-(k - path.size)) + 1
|
||||
#处理节点
|
||||
path << i
|
||||
backtracking(result, path, n, i + 1, k)
|
||||
#回溯,撤销处理过的节点
|
||||
path.pop
|
||||
end
|
||||
end
|
||||
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -159,7 +159,7 @@ public:
|
||||
|
||||
可以看出我依然还是用动规五部曲来进行分析,会把题目的方方面面都覆盖到!
|
||||
|
||||
**而且具体这五部分析是我自己平时总结的经验,找不出来第二个的,可能过一阵子 其他题解也会有动规五部曲了,哈哈**。
|
||||
**而且具体这五部分析是我自己平时总结的经验,找不出来第二个的,可能过一阵子 其他题解也会有动规五部曲了**。
|
||||
|
||||
当时我在用动规五部曲讲解斐波那契的时候,一些录友和我反应,感觉讲复杂了。
|
||||
|
||||
|
@ -249,9 +249,9 @@ public:
|
||||
|
||||
这道题目是一个简单题,但对于没接触过的同学还是有难度的。
|
||||
|
||||
所以初学者刚开始学习算法的时候,看到简单题目没有思路很正常,千万别怀疑自己智商,学习过程都是这样的,大家智商都差不多,哈哈。
|
||||
所以初学者刚开始学习算法的时候,看到简单题目没有思路很正常,千万别怀疑自己智商,学习过程都是这样的,大家智商都差不多。
|
||||
|
||||
只要把基本类型的题目都做过,总结过之后,思路自然就开阔了。
|
||||
只要把基本类型的题目都做过,总结过之后,思路自然就开阔了,加油💪
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
@ -300,7 +300,7 @@ public:
|
||||
|
||||
所以本题应该是一道hard题目了。
|
||||
|
||||
**可能刷过这道题目的录友都没感受到自己原来克服了这么多难点,就把这道题目AC了**,这应该叫做无招胜有招,人码合一,哈哈哈。
|
||||
**可能刷过这道题目的录友都没感受到自己原来克服了这么多难点,就把这道题目AC了**,这应该叫做无招胜有招,人码合一。
|
||||
|
||||
|
||||
|
||||
|
@ -187,7 +187,7 @@ public:
|
||||
|
||||
## 总结
|
||||
|
||||
这次可以说把环形链表这道题目的各个细节,完完整整的证明了一遍,说这是全网最详细讲解不为过吧,哈哈。
|
||||
这次可以说把环形链表这道题目的各个细节,完完整整的证明了一遍,说这是全网最详细讲解不为过吧。
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
@ -311,7 +311,7 @@ class Solution {
|
||||
```
|
||||
|
||||
```java
|
||||
//解法三:双反转+移位,在原始数组上进行反转。空间复杂度O(1)
|
||||
//解法三:双反转+移位,String 的 toCharArray() 方法底层会 new 一个和原字符串相同大小的 char 数组,空间复杂度:O(n)
|
||||
class Solution {
|
||||
/**
|
||||
* 思路:
|
||||
|
@ -240,6 +240,47 @@ class Solution:
|
||||
|
||||
```
|
||||
|
||||
### Rust
|
||||
|
||||
```rust
|
||||
|
||||
use std::collections::VecDeque;
|
||||
impl Solution {
|
||||
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
pub fn num_islands(grid: Vec<Vec<char>>) -> i32 {
|
||||
let mut visited = vec![vec![false; grid[0].len()]; grid.len()];
|
||||
let mut res = 0;
|
||||
for (i, chars) in grid.iter().enumerate() {
|
||||
for (j, &c) in chars.iter().enumerate() {
|
||||
if !visited[i][j] && c == '1' {
|
||||
res += 1;
|
||||
Self::bfs(&grid, &mut visited, (i as i32, j as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
pub fn bfs(grid: &Vec<Vec<char>>, visited: &mut Vec<Vec<bool>>, (x, y): (i32, i32)) {
|
||||
let mut queue = VecDeque::new();
|
||||
queue.push_back((x, y));
|
||||
visited[x as usize][y as usize] = true;
|
||||
while let Some((cur_x, cur_y)) = queue.pop_front() {
|
||||
for (dx, dy) in Self::DIRECTIONS {
|
||||
let (nx, ny) = (cur_x + dx, cur_y + dy);
|
||||
if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 {
|
||||
continue;
|
||||
}
|
||||
let (nx, ny) = (nx as usize, ny as usize);
|
||||
if grid[nx][ny] == '1' && !visited[nx][ny] {
|
||||
visited[nx][ny] = true;
|
||||
queue.push_back((nx as i32, ny as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -329,6 +329,42 @@ func numIslands(grid [][]byte) int {
|
||||
}
|
||||
```
|
||||
|
||||
### Rust:
|
||||
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
pub fn num_islands(grid: Vec<Vec<char>>) -> i32 {
|
||||
let mut visited = vec![vec![false; grid[0].len()]; grid.len()];
|
||||
let mut res = 0;
|
||||
for (i, chars) in grid.iter().enumerate() {
|
||||
for (j, &c) in chars.iter().enumerate() {
|
||||
if !visited[i][j] && c == '1' {
|
||||
res += 1;
|
||||
Self::dfs(&grid, &mut visited, (i as i32, j as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
pub fn dfs(grid: &Vec<Vec<char>>, visited: &mut Vec<Vec<bool>>, (x, y): (i32, i32)) {
|
||||
for (dx, dy) in Self::DIRECTIONS {
|
||||
let (nx, ny) = (x + dx, y + dy);
|
||||
if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 {
|
||||
continue;
|
||||
}
|
||||
let (nx, ny) = (nx as usize, ny as usize);
|
||||
if grid[nx][ny] == '1' && !visited[nx][ny] {
|
||||
visited[nx][ny] = true;
|
||||
Self::dfs(grid, visited, (nx as i32, ny as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -454,13 +454,34 @@ class MyStack:
|
||||
|
||||
def top(self) -> int:
|
||||
"""
|
||||
写法一:
|
||||
1. 首先确认不空
|
||||
2. 我们仅有in会存放数据,所以返回第一个即可
|
||||
2. 我们仅有in会存放数据,所以返回第一个即可(这里实际上用到了栈)
|
||||
写法二:
|
||||
1. 首先确认不空
|
||||
2. 因为队列的特殊性,FIFO,所以我们只有在pop()的时候才会使用queue_out
|
||||
3. 先把queue_in中的所有元素(除了最后一个),依次出列放进queue_out
|
||||
4. 交换in和out,此时out里只有一个元素
|
||||
5. 把out中的pop出来,即是原队列的最后一个,并使用temp变量暂存
|
||||
6. 把temp追加到queue_in的末尾
|
||||
"""
|
||||
# 写法一:
|
||||
# if self.empty():
|
||||
# return None
|
||||
|
||||
# return self.queue_in[-1] # 这里实际上用到了栈,因为直接获取了queue_in的末尾元素
|
||||
|
||||
# 写法二:
|
||||
if self.empty():
|
||||
return None
|
||||
|
||||
return self.queue_in[-1]
|
||||
for i in range(len(self.queue_in) - 1):
|
||||
self.queue_out.append(self.queue_in.popleft())
|
||||
|
||||
self.queue_in, self.queue_out = self.queue_out, self.queue_in
|
||||
temp = self.queue_out.popleft()
|
||||
self.queue_in.append(temp)
|
||||
return temp
|
||||
|
||||
|
||||
def empty(self) -> bool:
|
||||
@ -488,9 +509,19 @@ class MyStack:
|
||||
return self.que.popleft()
|
||||
|
||||
def top(self) -> int:
|
||||
# 写法一:
|
||||
# if self.empty():
|
||||
# return None
|
||||
# return self.que[-1]
|
||||
|
||||
# 写法二:
|
||||
if self.empty():
|
||||
return None
|
||||
return self.que[-1]
|
||||
for i in range(len(self.que)-1):
|
||||
self.que.append(self.que.popleft())
|
||||
temp = self.que.popleft()
|
||||
self.que.append(temp)
|
||||
return temp
|
||||
|
||||
def empty(self) -> bool:
|
||||
return not self.que
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
|
||||
工作中如果发现某一个功能自己要经常用,同事们可能也会用到,自己就花点时间把这个功能抽象成一个好用的函数或者工具类,不仅自己方便,也方便了同事们。
|
||||
|
||||
同事们就会逐渐认可你的工作态度和工作能力,自己的口碑都是这么一点一点积累起来的!在同事圈里口碑起来了之后,你就发现自己走上了一个正循环,以后的升职加薪才少不了你!哈哈哈
|
||||
同事们就会逐渐认可你的工作态度和工作能力,自己的口碑都是这么一点一点积累起来的!在同事圈里口碑起来了之后,你就发现自己走上了一个正循环,以后的升职加薪才少不了你!
|
||||
|
||||
|
||||
|
||||
|
@ -156,7 +156,7 @@ public:
|
||||
|
||||
但如果没有按照「代码随想录」的题目顺序来做的话,做动态规划或者做背包问题,上来就做这道题,那还是挺难的!
|
||||
|
||||
经过前面的训练这道题已经是简单题了,哈哈哈
|
||||
经过前面的训练这道题已经是简单题了
|
||||
|
||||
|
||||
|
||||
|
@ -151,6 +151,24 @@ function moveZeroes(nums: number[]): void {
|
||||
};
|
||||
```
|
||||
|
||||
### C
|
||||
|
||||
```c
|
||||
void moveZeroes(int* nums, int numsSize){
|
||||
int fastIndex = 0, slowIndex = 0;
|
||||
for (; fastIndex < numsSize; fastIndex++) {
|
||||
if (nums[fastIndex] != 0) {
|
||||
nums[slowIndex++] = nums[fastIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// 将slowIndex之后的元素变为0
|
||||
for (; slowIndex < numsSize; slowIndex++) {
|
||||
nums[slowIndex] = 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
|
||||
这也是大多数同学学习动态规划的苦恼所在,有的时候递推公式很简单,难在遍历顺序上!
|
||||
|
||||
但最终又可以稀里糊涂的把题目过了,也不知道为什么这样可以过,反正就是过了,哈哈
|
||||
但最终又可以稀里糊涂的把题目过了,也不知道为什么这样可以过,反正就是过了。
|
||||
|
||||
那么这篇文章就把遍历顺序分析的清清楚楚。
|
||||
|
||||
|
@ -216,7 +216,7 @@ public:
|
||||
|
||||
只不过平时我们习惯了在一维数组或者二维数组上推导公式,一下子换成了树,就需要对树的遍历方式足够了解!
|
||||
|
||||
大家还记不记得我在讲解贪心专题的时候,讲到这道题目:[贪心算法:我要监控二叉树!](https://programmercarl.com/0968.监控二叉树.html),这也是贪心算法在树上的应用。**那我也可以把这个算法起一个名字,叫做树形贪心**,哈哈哈
|
||||
大家还记不记得我在讲解贪心专题的时候,讲到这道题目:[贪心算法:我要监控二叉树!](https://programmercarl.com/0968.监控二叉树.html),这也是贪心算法在树上的应用。**那我也可以把这个算法起一个名字,叫做树形贪心**。
|
||||
|
||||
“树形贪心”词汇从此诞生,来自「代码随想录」
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
> 本周讲解了[贪心理论基础](https://programmercarl.com/贪心算法理论基础.html),以及第一道贪心的题目:[贪心算法:分发饼干](https://programmercarl.com/0455.分发饼干.html),可能会给大家一种贪心算法比较简单的错觉,好了,接下来几天的题目难度要上来了,哈哈。
|
||||
|
||||
# 376. 摆动序列
|
||||
|
||||
|
@ -100,7 +100,7 @@ for (int i = startIndex; i < nums.size(); i++) {
|
||||
}
|
||||
```
|
||||
|
||||
**对于已经习惯写回溯的同学,看到递归函数上面的`uset.insert(nums[i]);`,下面却没有对应的pop之类的操作,应该很不习惯吧,哈哈**
|
||||
**对于已经习惯写回溯的同学,看到递归函数上面的`uset.insert(nums[i]);`,下面却没有对应的pop之类的操作,应该很不习惯吧**
|
||||
|
||||
**这也是需要注意的点,`unordered_set<int> uset;` 是记录本层元素是否重复使用,新的一层uset都会重新定义(清空),所以要知道uset只负责本层!**
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
如果跟着「代码随想录」一起学过[回溯算法系列](https://programmercarl.com/回溯总结.html)的录友,看到这道题,应该有一种直觉,就是感觉好像回溯法可以爆搜出来。
|
||||
|
||||
事实确实如此,下面我也会给出相应的代码,只不过会超时,哈哈。
|
||||
事实确实如此,下面我也会给出相应的代码,只不过会超时。
|
||||
|
||||
这道题目咋眼一看和动态规划背包啥的也没啥关系。
|
||||
|
||||
|
@ -280,7 +280,7 @@ public:
|
||||
* [二叉树:前中后序迭代法](https://programmercarl.com/二叉树的迭代遍历.html)
|
||||
* [二叉树:前中后序统一风格的迭代方式](https://programmercarl.com/二叉树的统一迭代法.html)
|
||||
|
||||
下面我给出其中的一种中序遍历的迭代法,其中间处理逻辑一点都没有变(我从递归法直接粘过来的代码,连注释都没改,哈哈)
|
||||
下面我给出其中的一种中序遍历的迭代法,其中间处理逻辑一点都没有变(我从递归法直接粘过来的代码,连注释都没改)
|
||||
|
||||
代码如下:
|
||||
|
||||
|
@ -184,7 +184,7 @@ public:
|
||||
* 空间复杂度: O(m)
|
||||
|
||||
|
||||
是不是发现代码如此精简,哈哈
|
||||
是不是发现代码如此精简
|
||||
|
||||
## 总结
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
## 思路
|
||||
|
||||
这道题目还是挺简单的,大家不要想复杂了,一波哈希法又一波图论算法啥的,哈哈。
|
||||
这道题目还是挺简单的,大家不要想复杂了,一波哈希法又一波图论算法之类的。
|
||||
|
||||
其实就是,x,y坐标,初始为0,然后:
|
||||
* if (moves[i] == 'U') y++;
|
||||
|
@ -390,6 +390,147 @@ class Solution:
|
||||
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]):
|
||||
self.dfs(grid, visited, new_x, new_y)
|
||||
```
|
||||
|
||||
### Rust
|
||||
|
||||
dfs: 版本一
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
|
||||
pub fn max_area_of_island(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let mut visited = vec![vec![false; grid[0].len()]; grid.len()];
|
||||
|
||||
let mut res = 0;
|
||||
for (i, nums) in grid.iter().enumerate() {
|
||||
for (j, &num) in nums.iter().enumerate() {
|
||||
if !visited[i][j] && num == 1 {
|
||||
let mut count = 1;
|
||||
visited[i][j] = true;
|
||||
Self::dfs(&grid, &mut visited, (i as i32, j as i32), &mut count);
|
||||
res = res.max(count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn dfs(
|
||||
grid: &[Vec<i32>],
|
||||
visited: &mut [Vec<bool>],
|
||||
(x, y): (i32, i32),
|
||||
count: &mut i32,
|
||||
) {
|
||||
for (dx, dy) in Self::DIRECTIONS {
|
||||
let (nx, ny) = (x + dx, y + dy);
|
||||
if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 {
|
||||
continue;
|
||||
}
|
||||
let (nx, ny) = (nx as usize, ny as usize);
|
||||
if !visited[nx][ny] && grid[nx][ny] == 1 {
|
||||
visited[nx][ny] = true;
|
||||
*count += 1;
|
||||
Self::dfs(grid, visited, (nx as i32, ny as i32), count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
dfs: 版本二
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
|
||||
pub fn max_area_of_island(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let mut visited = vec![vec![false; grid[0].len()]; grid.len()];
|
||||
|
||||
let mut res = 0;
|
||||
for (i, nums) in grid.iter().enumerate() {
|
||||
for (j, &num) in nums.iter().enumerate() {
|
||||
if !visited[i][j] && num == 1 {
|
||||
let mut count = 0;
|
||||
Self::dfs(&grid, &mut visited, (i as i32, j as i32), &mut count);
|
||||
res = res.max(count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn dfs(
|
||||
grid: &[Vec<i32>],
|
||||
visited: &mut [Vec<bool>],
|
||||
(x, y): (i32, i32),
|
||||
count: &mut i32,
|
||||
) {
|
||||
if visited[x as usize][y as usize] || grid[x as usize][y as usize] == 0 {
|
||||
return;
|
||||
}
|
||||
visited[x as usize][y as usize] = true;
|
||||
*count += 1;
|
||||
for (dx, dy) in Self::DIRECTIONS {
|
||||
let (nx, ny) = (x + dx, y + dy);
|
||||
if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 {
|
||||
continue;
|
||||
}
|
||||
Self::dfs(grid, visited, (nx, ny), count);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
bfs:
|
||||
|
||||
```rust
|
||||
use std::collections::VecDeque;
|
||||
impl Solution {
|
||||
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
|
||||
pub fn max_area_of_island(grid: Vec<Vec<i32>>) -> i32 {
|
||||
let mut visited = vec![vec![false; grid[0].len()]; grid.len()];
|
||||
|
||||
let mut res = 0;
|
||||
for (i, nums) in grid.iter().enumerate() {
|
||||
for (j, &num) in nums.iter().enumerate() {
|
||||
if !visited[i][j] && num == 1 {
|
||||
let mut count = 0;
|
||||
Self::bfs(&grid, &mut visited, (i as i32, j as i32), &mut count);
|
||||
res = res.max(count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn bfs(grid: &[Vec<i32>], visited: &mut [Vec<bool>], (x, y): (i32, i32), count: &mut i32) {
|
||||
let mut queue = VecDeque::new();
|
||||
queue.push_back((x, y));
|
||||
visited[x as usize][y as usize] = true;
|
||||
*count += 1;
|
||||
while let Some((cur_x, cur_y)) = queue.pop_front() {
|
||||
for (dx, dy) in Self::DIRECTIONS {
|
||||
let (nx, ny) = (cur_x + dx, cur_y + dy);
|
||||
if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 {
|
||||
continue;
|
||||
}
|
||||
let (nx, ny) = (nx as usize, ny as usize);
|
||||
if !visited[nx][ny] && grid[nx][ny] == 1 {
|
||||
visited[nx][ny] = true;
|
||||
queue.push_back((nx as i32, ny as i32));
|
||||
*count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -82,7 +82,7 @@ if (root == NULL) {
|
||||
|
||||
此时要明确,需要遍历整棵树么?
|
||||
|
||||
别忘了这是搜索树,遍历整棵搜索树简直是对搜索树的侮辱,哈哈。
|
||||
别忘了这是搜索树,遍历整棵搜索树简直是对搜索树的侮辱。
|
||||
|
||||
搜索树是有方向了,可以根据插入元素的数值,决定递归方向。
|
||||
|
||||
|
@ -245,7 +245,29 @@ func allPathsSourceTarget(graph [][]int) [][]int {
|
||||
|
||||
```
|
||||
|
||||
### Rust
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn all_paths_source_target(graph: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
|
||||
let (mut res, mut path) = (vec![], vec![0]);
|
||||
Self::dfs(&graph, &mut path, &mut res, 0);
|
||||
res
|
||||
}
|
||||
|
||||
pub fn dfs(graph: &Vec<Vec<i32>>, path: &mut Vec<i32>, res: &mut Vec<Vec<i32>>, node: usize) {
|
||||
if node == graph.len() - 1 {
|
||||
res.push(path.clone());
|
||||
return;
|
||||
}
|
||||
for &v in &graph[node] {
|
||||
path.push(v);
|
||||
Self::dfs(graph, path, res, v as usize);
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
@ -491,6 +491,89 @@ class Solution:
|
||||
return ans
|
||||
```
|
||||
|
||||
### Rust
|
||||
|
||||
dfs:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
|
||||
pub fn num_enclaves(mut grid: Vec<Vec<i32>>) -> i32 {
|
||||
for i in 0..grid.len() {
|
||||
for j in 0..grid[0].len() {
|
||||
if (i == 0 || i == grid.len() - 1 || j == 0 || j == grid[0].len() - 1)
|
||||
&& grid[i][j] == 1
|
||||
{
|
||||
Self::dfs(&mut grid, (i as i32, j as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
grid.iter()
|
||||
.map(|nums| nums.iter().filter(|&&num| num == 1).count() as i32)
|
||||
.sum()
|
||||
}
|
||||
|
||||
pub fn dfs(grid: &mut [Vec<i32>], (x, y): (i32, i32)) {
|
||||
grid[x as usize][y as usize] = 0;
|
||||
for (dx, dy) in Self::DIRECTIONS {
|
||||
let (nx, ny) = (x + dx, y + dy);
|
||||
if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 {
|
||||
continue;
|
||||
}
|
||||
if grid[nx as usize][ny as usize] == 0 {
|
||||
continue;
|
||||
}
|
||||
Self::dfs(grid, (nx, ny));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
bfs:
|
||||
|
||||
```rust
|
||||
use std::collections::VecDeque;
|
||||
impl Solution {
|
||||
const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
|
||||
|
||||
pub fn num_enclaves(mut grid: Vec<Vec<i32>>) -> i32 {
|
||||
for i in 0..grid.len() {
|
||||
for j in 0..grid[0].len() {
|
||||
if (i == 0 || i == grid.len() - 1 || j == 0 || j == grid[0].len() - 1)
|
||||
&& grid[i][j] == 1
|
||||
{
|
||||
// Self::dfs(&mut grid, (i as i32, j as i32));
|
||||
Self::bfs(&mut grid, (i as i32, j as i32));
|
||||
}
|
||||
}
|
||||
}
|
||||
grid.iter()
|
||||
.map(|nums| nums.iter().filter(|&&num| num == 1).count() as i32)
|
||||
.sum()
|
||||
}
|
||||
|
||||
pub fn bfs(grid: &mut [Vec<i32>], (x, y): (i32, i32)) {
|
||||
let mut queue = VecDeque::new();
|
||||
queue.push_back((x, y));
|
||||
grid[x as usize][y as usize] = 0;
|
||||
while let Some((cur_x, cur_y)) = queue.pop_front() {
|
||||
for (dx, dy) in Self::DIRECTIONS {
|
||||
let (nx, ny) = (cur_x + dx, cur_y + dy);
|
||||
if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if grid[nx as usize][ny as usize] == 0 {
|
||||
continue;
|
||||
}
|
||||
queue.push_back((nx, ny));
|
||||
grid[nx as usize][ny as usize] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## 类似题目
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230516112821.png' width=500 alt=''> </img></div>
|
||||
|
||||
星球里的录友都可以得到我1V1的指导,**我已经详细回答了7000+个问题**: (这个回答问题数量,可以看出我有劳模的潜质 哈哈)
|
||||
星球里的录友都可以得到我1V1的指导,**我已经详细回答了7000+个问题**: (这个回答问题数量,可以看出我有劳模的潜质 )
|
||||
|
||||
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230426103803.png' width=500 alt=''> </img></div>
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230607171843.png' width=400 alt=''> </img></div>
|
||||
|
||||
|
||||
一些录友当初也是进来 白嫖一波资料,就退款跑了 哈哈哈,不过后面又加回来,例如这位录友:
|
||||
一些录友当初也是进来 白嫖一波资料,就退款跑了,不过后面又加回来,例如这位录友:
|
||||
|
||||
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20220516160948.png' width=500 alt=''> </img></div>
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
这真是一个好问题,而且我一句两句还说不清楚,所以就专门发文来讲一讲。
|
||||
|
||||
同时我还录制的一期视频,哈哈我的视频号,大家可以关注一波。
|
||||
同时我还录制的一期视频,我的视频号,大家可以关注一波。
|
||||
|
||||
|
||||
一说到服务器,可能很多人都说搞分布式,做计算,搞爬虫,做程序后台服务,多人合作等等。
|
||||
@ -57,7 +57,7 @@
|
||||
|
||||
https://github.com/youngyangyang04/fileHttpServer
|
||||
|
||||
感兴趣的录友可以去学习一波,顺便给个star 哈哈
|
||||
感兴趣的录友可以去学习一波,顺便给个star。
|
||||
|
||||
|
||||
## 网站
|
||||
|
@ -4,10 +4,6 @@
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
相信每一位录友都接触过时间复杂度,「代码随想录」已经也讲了一百多道经典题目了,是时候对时间复杂度来一个深度的剖析了,很早之前就写过一篇,当时文章还没有人看,Carl感觉有价值的东西值得让更多的人看到,哈哈。
|
||||
|
||||
所以重新整理的时间复杂度文章,正式和大家见面啦!
|
||||
|
||||
# 时间复杂度
|
||||
|
||||
## 究竟什么是时间复杂度
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
但这里我并不是说IDE不好用,IDE在 代码跟踪,引用跳转等等其实是很给力的,效率比vim高。
|
||||
|
||||
我用vim的话,如果需要跟踪代码的话,就用ctag去跳转,虽然很不智能(是基于规则匹配,不是语义匹配),但加上我自己的智能就也能用(这里真的要看对代码的把握程度了,哈哈哈)
|
||||
我用vim的话,如果需要跟踪代码的话,就用ctag去跳转,虽然很不智能(是基于规则匹配,不是语义匹配),但加上我自己的智能就也能用(这里真的要看对代码的把握程度了)
|
||||
|
||||
所以连跟踪代码都不用IDE的话,其他方面那我就更用不上IDE了。
|
||||
|
||||
@ -99,5 +99,5 @@ Github地址:[https://github.com/youngyangyang04/PowerVim](https://github.com/
|
||||
|
||||
Gitee地址:[https://gitee.com/programmercarl/power-vim](https://gitee.com/programmercarl/power-vim)
|
||||
|
||||
最后,因为这个vim配置因为我一直没有宣传,所以star数量很少,哈哈哈,录友们去给个star吧,真正的开发利器,值得顶起来!
|
||||
最后,因为这个vim配置因为我一直没有宣传,所以star数量很少,录友们去给个star吧,真正的开发利器,值得顶起来!
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
* 第二种情况:这个项目没赚到钱,半死不活的,代码还没有设计也没有规范,这样对技术人员的伤害就非常大了。
|
||||
|
||||
**而不注重代码风格的团队,99.99%都是第二种情况**,如果你赶上了第一种情况,那就恭喜你了,本文下面的内容可以不用看了,哈哈。
|
||||
**而不注重代码风格的团队,99.99%都是第二种情况**,如果你赶上了第一种情况,那就恭喜你了,本文下面的内容可以不用看了。
|
||||
|
||||
## 代码规范
|
||||
|
||||
|
@ -53,7 +53,7 @@ int main() {
|
||||
|
||||
代码中可以看出,其实就是定义个main函数,构造个输入用例,然后定义一个solution变量,调用minCostClimbingStairs函数就可以了。
|
||||
|
||||
此时大家就可以随意构造测试数据,然后想怎么打日志就怎么打日志,没有找不出的bug,哈哈。
|
||||
此时大家就可以随意构造测试数据,然后想怎么打日志就怎么打日志,没有找不出的bug。
|
||||
|
||||
|
||||
|
||||
|
@ -94,9 +94,6 @@
|
||||
* 自如网
|
||||
* 汽车之家
|
||||
|
||||
## 总结
|
||||
|
||||
可能是我写总结写习惯了,什么文章都要有一个总结,哈哈,那么我就总结一下。
|
||||
|
||||
北京的互联网氛围绝对是最好的(暂不讨论户口和房价问题),大家如果看了[深圳原来有这么多互联网公司,你都知道么?](https://programmercarl.com/前序/深圳互联网公司总结.html)这篇之后,**会发现北京互联网外企和二线互联网公司数量多的优势,在深圳的互联网公司断档比较严重,如果去不了为数不多的一线公司,可选择的余地就非常少了,而北京选择的余地就很多!**
|
||||
|
||||
|
@ -113,13 +113,6 @@ Carl校招社招都拿过大厂的offer,同时也看过很多应聘者的简
|
||||
|
||||
**好的简历是敲门砖,同时也不要在简历上花费过多的精力,好的简历以及面试技巧都是锦上添花**,真的求得心得的offer靠的还是真才实学。
|
||||
|
||||
如何真才实学呢? 跟着「代码随想录」一起刷题呀,哈哈
|
||||
|
||||
大家此时可以再重审一遍自己的简历,如果发现哪里的不足,面试前要多准备多练习。
|
||||
|
||||
就酱,「代码随想录」就是这么干货,Carl多年积累的简历技巧都毫不保留的写出来了,如果感觉对你有帮助,就宣传一波「代码随想录」吧,值得大家的关注!
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码.jpg width=450> </img></div>
|
||||
|
@ -131,7 +131,7 @@ int function3(int x, int n) {
|
||||
return function3(x, n / 2) * function3(x, n / 2);
|
||||
}
|
||||
```
|
||||
可以看出这道题目非常简单,但是又很考究算法的功底,特别是对递归的理解,这也是我面试别人的时候用过的一道题,所以整个情景我才写的如此逼真,哈哈。
|
||||
可以看出这道题目非常简单,但是又很考究算法的功底,特别是对递归的理解,这也是我面试别人的时候用过的一道题,所以整个情景我才写的如此逼真。
|
||||
|
||||
大厂面试的时候最喜欢用“简单题”来考察候选人的算法功底,注意这里的“简单题”可并不一定真的简单哦!
|
||||
|
||||
|
@ -69,7 +69,7 @@ public:
|
||||
* 时间复杂度: O(n)
|
||||
* 空间复杂度:O(1)
|
||||
|
||||
是不是发现这代码也太简单了,哈哈。
|
||||
是不是发现这代码也太简单了。
|
||||
|
||||
## 总结
|
||||
|
||||
@ -120,7 +120,8 @@ class Solution {
|
||||
```
|
||||
|
||||
```java
|
||||
//解法二:空间复杂度:O(1)。用原始数组来进行反转操作
|
||||
// 解法二
|
||||
// 空间复杂度:O(n)。String 的 toCharArray() 方法底层会 new 一个和原字符串相同大小的 char 数组
|
||||
// 思路为:先整个字符串反转,再反转前面的,最后反转后面 n 个
|
||||
class Solution {
|
||||
public String reverseLeftWords(String s, int n) {
|
||||
|
@ -135,7 +135,7 @@ public:
|
||||
|
||||
看完这篇文章,去leetcode上怒刷五题,文章中 编号107题目的样例图放错了(原谅我匆忙之间总是手抖),但不影响大家理解。
|
||||
|
||||
只有同学发现leetcode上“515. 在每个树行中找最大值”,也是层序遍历的应用,依然可以分分钟解决,所以就是一鼓作气解决六道了,哈哈。
|
||||
只有同学发现leetcode上“515. 在每个树行中找最大值”,也是层序遍历的应用,依然可以分分钟解决,所以就是一鼓作气解决六道了。
|
||||
|
||||
**层序遍历遍历相对容易一些,只要掌握基本写法(也就是框架模板),剩下的就是在二叉树每一行遍历的时候做做逻辑修改。**
|
||||
|
||||
|
@ -70,7 +70,7 @@
|
||||
|
||||
**但可以遍历一遍就可以求众数集合,使用了适时清空结果集的方法**,这个方法还是很巧妙的。相信仔细读了文章的同学会惊呼其巧妙!
|
||||
|
||||
**所以大家不要看题目简单了,就不动手做了,我选的题目,一般不会简单到不用动手的程度,哈哈**。
|
||||
**所以大家不要看题目简单了,就不动手做了,我选的题目,一般不会简单到不用动手的程度**。
|
||||
|
||||
## 周六
|
||||
|
||||
|
@ -98,7 +98,7 @@
|
||||
|
||||
对于回溯法的整体框架,网上搜的文章这块一般都说不清楚,按照天上掉下来的代码对着讲解,不知道究竟是怎么来的,也不知道为什么要这么写。
|
||||
|
||||
所以,录友们刚开始学回溯法,起跑姿势就很标准了,哈哈。
|
||||
所以,录友们刚开始学回溯法,起跑姿势就很标准了。
|
||||
|
||||
下周依然是回溯法,难度又要上升一个台阶了。
|
||||
|
||||
|
@ -148,7 +148,7 @@ if (startIndex >= nums.size()) { // 终止条件可以不加
|
||||
|
||||
**我讲解每一种问题,都会和其他问题作对比,做分析,所以只要跟着细心琢磨相信对回溯又有新的认识**。
|
||||
|
||||
最近这两天题目有点难度,刚刚开始学回溯算法的话,按照现在这个每天一题的速度来,确实有点快,学起来吃力非常正常,这些题目都是我当初学了好几个月才整明白的,哈哈。
|
||||
最近这两天题目有点难度,刚刚开始学回溯算法的话,按照现在这个每天一题的速度来,确实有点快,学起来吃力非常正常,这些题目都是我当初学了好几个月才整明白的。
|
||||
|
||||
**所以大家能跟上的话,已经很优秀了!**
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
||||
|
||||
## 周四
|
||||
|
||||
这道题目:[贪心算法:K次取反后最大化的数组和](https://programmercarl.com/1005.K次取反后最大化的数组和.html)就比较简单了,哈哈,用简单题来讲一讲贪心的思想。
|
||||
这道题目:[贪心算法:K次取反后最大化的数组和](https://programmercarl.com/1005.K次取反后最大化的数组和.html)就比较简单了,用简单题来讲一讲贪心的思想。
|
||||
|
||||
**这里其实用了两次贪心!**
|
||||
|
||||
@ -76,8 +76,6 @@
|
||||
|
||||
第二次贪心:局部最优:只找数值最小的正整数进行反转,当前数值可以达到最大(例如正整数数组{5, 3, 1},反转1 得到-1 比 反转5得到的-5 大多了),全局最优:整个 数组和 达到最大。
|
||||
|
||||
[贪心算法:K次取反后最大化的数组和](https://programmercarl.com/1005.K次取反后最大化的数组和.html)中的代码,最后while处理K的时候,其实直接判断奇偶数就可以了,文中给出的方式太粗暴了,哈哈,Carl大意了。
|
||||
|
||||
例外一位录友留言给出一个很好的建议,因为文中是使用快排,仔细看题,**题目中限定了数据范围是正负一百,所以可以使用桶排序**,这样时间复杂度就可以优化为$O(n)$了。但可能代码要复杂一些了。
|
||||
|
||||
|
||||
@ -85,7 +83,7 @@
|
||||
|
||||
大家会发现本周的代码其实都简单,但思路却很巧妙,并不容易写出来。
|
||||
|
||||
如果是第一次接触的话,其实很难想出来,就是接触过之后就会了,所以大家不用感觉自己想不出来而烦躁,哈哈。
|
||||
如果是第一次接触的话,其实很难想出来,就是接触过之后就会了,所以大家不用感觉自己想不出来而烦躁。
|
||||
|
||||
相信此时大家现在对贪心算法又有一个新的认识了,加油💪
|
||||
|
||||
|
@ -107,7 +107,7 @@
|
||||
|
||||
本周讲解的内容都是经常被大家忽略的知识点,而通常这种知识点,才最能发现一位候选人的编程功底。
|
||||
|
||||
因为之前一直都是在持续更新算法题目的文章,这周说一说算法性能分析,感觉也是换了换口味,哈哈。
|
||||
因为之前一直都是在持续更新算法题目的文章,这周说一说算法性能分析,感觉也是换了换口味。
|
||||
|
||||
同时大家也会发现,**大厂面试官最喜欢用“简单题”(就是看起来很简单,其实非常考验技术功底的题目),而不是要手撕红黑树之类的**。
|
||||
|
||||
|
@ -95,7 +95,7 @@
|
||||
|
||||
虽然有时候感觉贪心就是常识,但如果真正是常识性的题目,其实是模拟题,就不是贪心算法了!例如[贪心算法:加油站](https://programmercarl.com/0134.加油站.html)中的贪心方法一,其实我就认为不是贪心算法,而是直接从全局最优的角度上来模拟,因为方法里没有体现局部最优的过程。
|
||||
|
||||
而且大家也会发现,贪心并没有想象中的那么简单,贪心往往妙的出其不意,触不及防!哈哈
|
||||
而且大家也会发现,贪心并没有想象中的那么简单,贪心往往妙的出其不意,触不及防!
|
||||
|
||||
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码.jpg width=450> </img></div>
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
|
||||
本周的主题就是用贪心算法来解决区间问题,经过本周的学习,大家应该对区间的各种合并分割有一定程度的了解了。
|
||||
|
||||
其实很多区间的合并操作看起来都是常识,其实贪心算法有时候就是常识,哈哈,但也别小看了贪心算法。
|
||||
其实很多区间的合并操作看起来都是常识,其实贪心算法有时候就是常识,但也别小看了贪心算法。
|
||||
|
||||
在[贪心算法:合并区间](https://programmercarl.com/0056.合并区间.html)中就说过,对于贪心算法,很多同学都是:「如果能凭常识直接做出来,就会感觉不到自己用了贪心, 一旦第一直觉想不出来, 可能就一直想不出来了」。
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
后序我们在讲解动规的题目时候,都离不开这五步!
|
||||
|
||||
本周都是简单题目,大家可能会感觉 按照这五部来好麻烦,凭感觉随手一写,直接就过,越到后面越会感觉,凭感觉这个事还是不靠谱的,哈哈。
|
||||
本周都是简单题目,大家可能会感觉 按照这五部来好麻烦,凭感觉随手一写,直接就过,越到后面越会感觉,凭感觉这个事还是不靠谱的。
|
||||
|
||||
最后我们讲了动态规划题目应该如何debug,相信一些录友做动规的题目,一旦报错也是凭感觉来改。
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
2. 我打印dp数组的日志了么?
|
||||
3. 打印出来了dp数组和我想的一样么?
|
||||
|
||||
哈哈,专治各种代码写出来了但AC不了的疑难杂症。
|
||||
专治各种代码写出来了但AC不了的疑难杂症。
|
||||
|
||||
## 周二
|
||||
|
||||
@ -60,7 +60,7 @@ for (int i = 3; i <= n; i++) { // 注意i是从3开始的
|
||||
}
|
||||
```
|
||||
|
||||
这个可以是面试的一个小问题,哈哈,考察候选人对dp[i]定义的理解程度。
|
||||
这个可以是面试的一个小问题,考察候选人对dp[i]定义的理解程度。
|
||||
|
||||
这道题目还可以继续深化,就是一步一个台阶,两个台阶,三个台阶,直到 m个台阶,有多少种方法爬到n阶楼顶。
|
||||
|
||||
@ -86,7 +86,7 @@ public:
|
||||
|
||||
代码中m表示最多可以爬m个台阶。
|
||||
|
||||
**以上代码不能运行哈,我主要是为了体现只要把m换成2,粘过去,就可以AC爬楼梯这道题,不信你就粘一下试试,哈哈**。
|
||||
**以上代码不能运行哈,我主要是为了体现只要把m换成2,粘过去,就可以AC爬楼梯这道题,不信你就粘一下试试**。
|
||||
|
||||
|
||||
**此时我就发现一个绝佳的大厂面试题**,第一道题就是单纯的爬楼梯,然后看候选人的代码实现,如果把dp[0]的定义成1了,就可以发难了,为什么dp[0]一定要初始化为1,此时可能候选人就要强行给dp[0]应该是1找各种理由。那这就是一个考察点了,对dp[i]的定义理解的不深入。
|
||||
@ -97,7 +97,7 @@ public:
|
||||
|
||||
**其实大厂面试最喜欢问题的就是这种简单题,然后慢慢变化,在小细节上考察候选人**。
|
||||
|
||||
这道绝佳的面试题我没有用过,如果录友们有面试别人的需求,就把这个套路拿去吧,哈哈哈。
|
||||
这道绝佳的面试题我没有用过,如果录友们有面试别人的需求,就把这个套路拿去吧。
|
||||
|
||||
我在[通过一道面试题目,讲一讲递归算法的时间复杂度!](https://programmercarl.com/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.html)中,以我自己面试别人的真实经历,通过求x的n次方 这么简单的题目,就可以考察候选人对算法性能以及递归的理解深度,录友们可以看看,绝对有收获!
|
||||
|
||||
@ -138,7 +138,7 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
这么写看上去比较顺,但是就是感觉和题目描述的不太符。哈哈,也没有必要这么细扣题意了,大家只要知道,题目的意思反正就是要不是第一步不花费,要不是最后一步不花费,都可以。
|
||||
这么写看上去比较顺,但是就是感觉和题目描述的不太符。也没有必要这么细扣题意了,大家只要知道,题目的意思反正就是要不是第一步不花费,要不是最后一步不花费,都可以。
|
||||
|
||||
## 总结
|
||||
|
||||
|
@ -151,12 +151,6 @@ n为5时候的dp数组状态如图:
|
||||
|
||||
我现在也陷入了纠结,题目一简单,就会有录友和我反馈说题目太简单了,题目一难,阅读量就特别低。
|
||||
|
||||
我也好难那,哈哈哈。
|
||||
|
||||
**但我还会坚持规划好的路线,难度循序渐进,并以面试经典题目为准,该简单的时候就是简单,同时也不会因为阅读量低就放弃有难度的题目!**。
|
||||
|
||||
录友们看到这是不是得给个Carl点个赞啊[让我看看]。
|
||||
|
||||
预告,我们下周正式开始讲解背包问题,经典的不能再经典,也是比较难的一类动态规划的题目了,录友们上车抓稳咯。
|
||||
|
||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码.jpg width=450> </img></div>
|
||||
|
@ -187,7 +187,7 @@ return {val2, val1};
|
||||
|
||||
因为平时我们习惯了在一维数组或者二维数组上推导公式,一下子换成了树,就需要对树的遍历方式足够了解!
|
||||
|
||||
大家还记不记得我在讲解贪心专题的时候,讲到这道题目:[贪心算法:我要监控二叉树!](https://programmercarl.com/0968.监控二叉树.html),这也是贪心算法在树上的应用。**那我也可以把这个算法起一个名字,叫做树形贪心**,哈哈哈
|
||||
大家还记不记得我在讲解贪心专题的时候,讲到这道题目:[贪心算法:我要监控二叉树!](https://programmercarl.com/0968.监控二叉树.html),这也是贪心算法在树上的应用。**那我也可以把这个算法起一个名字,叫做树形贪心**
|
||||
|
||||
“树形贪心”词汇从此诞生,来自「代码随想录」
|
||||
|
||||
@ -301,7 +301,7 @@ public:
|
||||
|
||||
那么这里每一种情况 我在文章中都做了详细的介绍。
|
||||
|
||||
周四我们开始讲解股票系列了,大家应该预测到了,我们下周的主题就是股票! 哈哈哈,多么浮躁的一个系列!敬请期待吧!
|
||||
周四我们开始讲解股票系列了,大家应该预测到了,我们下周的主题就是股票!敬请期待吧!
|
||||
|
||||
**代码随想录温馨提醒:投资有风险,入市需谨慎!**
|
||||
|
||||
|
@ -139,7 +139,7 @@ public:
|
||||
|
||||
看完这篇文章,去leetcode上怒刷五题,文章中 编号107题目的样例图放错了(原谅我匆忙之间总是手抖),但不影响大家理解。
|
||||
|
||||
只有同学发现leetcode上“515. 在每个树行中找最大值”,也是层序遍历的应用,依然可以分分钟解决,所以就是一鼓作气解决六道了,哈哈。
|
||||
只有同学发现leetcode上“515. 在每个树行中找最大值”,也是层序遍历的应用,依然可以分分钟解决,所以就是一鼓作气解决六道了。
|
||||
|
||||
**层序遍历遍历相对容易一些,只要掌握基本写法(也就是框架模板),剩下的就是在二叉树每一行遍历的时候做做逻辑修改。**
|
||||
|
||||
|
@ -347,7 +347,7 @@ used数组可是全局变量,每层与每层之间公用一个used数组,所
|
||||
|
||||
**这里我明确给出了棋盘的宽度就是for循环的长度,递归的深度就是棋盘的高度,这样就可以套进回溯法的模板里了**。
|
||||
|
||||
相信看完本篇[回溯算法:N皇后问题](https://programmercarl.com/0051.N皇后.html)也没那么难了,传说已经不是传说了,哈哈。
|
||||
相信看完本篇[回溯算法:N皇后问题](https://programmercarl.com/0051.N皇后.html)也没那么难了,传说已经不是传说了。
|
||||
|
||||
|
||||
|
||||
|
@ -283,14 +283,13 @@ join(1, 8);
|
||||
join(3, 8);
|
||||
join(1, 7);
|
||||
join(8, 5);
|
||||
join(6, 2);
|
||||
join(2, 9);
|
||||
|
||||
join(6, 2);
|
||||
```
|
||||
|
||||
此时我们生成的的有向图为:
|
||||
|
||||

|
||||

|
||||
|
||||
有录友可能想,`join(3, 8)` 在图中为什么 将 元素1 连向元素 3 而不是将 元素 8 连向 元素 3 呢?
|
||||
|
||||
|
@ -154,13 +154,13 @@ public:
|
||||
|
||||
所以对于两种使用数组的方法一和方法三,也不好确定谁优,但一定都没有使用方法二链表的效率高!
|
||||
|
||||
一波分析之后,对于[贪心算法:根据身高重建队列](https://programmercarl.com/0406.根据身高重建队列.html) ,大家就安心使用链表吧!别折腾了,哈哈,相当于我替大家折腾了一下。
|
||||
一波分析之后,对于[贪心算法:根据身高重建队列](https://programmercarl.com/0406.根据身高重建队列.html) ,大家就安心使用链表吧!别折腾了,相当于我替大家折腾了一下。
|
||||
|
||||
## 总结
|
||||
|
||||
大家应该发现了,编程语言中一个普通容器的insert,delete的使用,都可能对写出来的算法的有很大影响!
|
||||
|
||||
如果抛开语言谈算法,除非从来不用代码写算法纯分析,**否则的话,语言功底不到位O(n)的算法可以写出O(n^2)的性能**,哈哈。
|
||||
如果抛开语言谈算法,除非从来不用代码写算法纯分析,**否则的话,语言功底不到位O(n)的算法可以写出O(n^2)的性能**。
|
||||
|
||||
相信在这里学习算法的录友们,都是想在软件行业长远发展的,都是要从事编程的工作,那么一定要深耕好一门编程语言,这个非常重要!
|
||||
|
||||
|
@ -173,7 +173,7 @@ int main() {
|
||||
|
||||
这个区别,我将在后面讲解具体leetcode题目中给大家介绍,因为这块如果不结合具题目,单纯的介绍原理估计很多同学会越看越懵!
|
||||
|
||||
别急,下一篇就是了!哈哈
|
||||
别急,下一篇就是了!
|
||||
|
||||
最后,**又可以出一道面试题了,就是纯完全背包,要求先用二维dp数组实现,然后再用一维dp数组实现,最后再问,两个for循环的先后是否可以颠倒?为什么?**
|
||||
这个简单的完全背包问题,估计就可以难住不少候选人了。
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
在刚刚讲过的回溯系列中,大家可以发现我是严格按照框架难度顺序循序渐进讲解的,**和贪心又不一样,因为回溯法如果题目顺序没选好,刷题效果会非常差!**
|
||||
|
||||
同样回溯系列也不允许简单困难交替着来,因为前后题目都是有因果关系的,**相信跟着刷过回溯系列的录友们都会明白我的良苦用心,哈哈**。
|
||||
同样回溯系列也不允许简单困难交替着来,因为前后题目都是有因果关系的,**相信跟着刷过回溯系列的录友们都会明白我的良苦用心**。
|
||||
|
||||
**每个系列都有每个系列的特点,我都会根据特点有所调整,大家看我每天的推送的题目,都不是随便找一个到就推送的,都是先有整体规划,然后反复斟酌具体题目的结果**。
|
||||
|
||||
@ -116,7 +116,7 @@ Carl个人认为:如果找出局部最优并可以推出全局最优,就是
|
||||
|
||||
周总结里会对每周的题目中大家的疑问、相关难点或者笔误之类的进行复盘和总结。
|
||||
|
||||
如果大家发现文章哪里有问题,那么在周总结里或者文章评论区一定进行了修正,保证不会因为我的笔误或者理解问题而误导大家,哈哈。
|
||||
如果大家发现文章哪里有问题,那么在周总结里或者文章评论区一定进行了修正,保证不会因为我的笔误或者理解问题而误导大家。
|
||||
|
||||
所以周总结一定要看!
|
||||
|
||||
|
@ -241,6 +241,16 @@ impl<T> ListNode<T> {
|
||||
```
|
||||
|
||||
|
||||
### C:
|
||||
|
||||
```c
|
||||
typedef struct ListNodeT {
|
||||
int val;
|
||||
struct ListNodeT next;
|
||||
} ListNode;
|
||||
```
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
Reference in New Issue
Block a user