mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 00:43:04 +08:00
Merge branch 'master' of github.com:jinbudaily/leetcode-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)
|
||||
|
||||
(持续更新中....)
|
||||
|
||||
|
@ -211,10 +211,6 @@ class Solution:
|
||||
|
||||
```javascript
|
||||
|
||||
/**
|
||||
* @param {number} n
|
||||
* @return {number[][]}
|
||||
*/
|
||||
var generateMatrix = function(n) {
|
||||
let startX = startY = 0; // 起始位置
|
||||
let loop = Math.floor(n/2); // 旋转圈数
|
||||
@ -226,11 +222,11 @@ var generateMatrix = function(n) {
|
||||
while (loop--) {
|
||||
let row = startX, col = startY;
|
||||
// 上行从左到右(左闭右开)
|
||||
for (; col < startY + n - offset; col++) {
|
||||
for (; col < n - offset; col++) {
|
||||
res[row][col] = count++;
|
||||
}
|
||||
// 右列从上到下(左闭右开)
|
||||
for (; row < startX + n - offset; row++) {
|
||||
for (; row < n - offset; row++) {
|
||||
res[row][col] = count++;
|
||||
}
|
||||
// 下行从右到左(左闭右开)
|
||||
@ -247,7 +243,7 @@ var generateMatrix = function(n) {
|
||||
startY++;
|
||||
|
||||
// 更新offset
|
||||
offset += 2;
|
||||
offset += 1;
|
||||
}
|
||||
// 如果n为奇数的话,需要单独给矩阵最中间的位置赋值
|
||||
if (n % 2 === 1) {
|
||||
@ -257,6 +253,7 @@ var generateMatrix = function(n) {
|
||||
};
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
### TypeScript:
|
||||
|
@ -159,7 +159,7 @@ public:
|
||||
|
||||
可以看出我依然还是用动规五部曲来进行分析,会把题目的方方面面都覆盖到!
|
||||
|
||||
**而且具体这五部分析是我自己平时总结的经验,找不出来第二个的,可能过一阵子 其他题解也会有动规五部曲了,哈哈**。
|
||||
**而且具体这五部分析是我自己平时总结的经验,找不出来第二个的,可能过一阵子 其他题解也会有动规五部曲了**。
|
||||
|
||||
当时我在用动规五部曲讲解斐波那契的时候,一些录友和我反应,感觉讲复杂了。
|
||||
|
||||
|
@ -249,9 +249,9 @@ public:
|
||||
|
||||
这道题目是一个简单题,但对于没接触过的同学还是有难度的。
|
||||
|
||||
所以初学者刚开始学习算法的时候,看到简单题目没有思路很正常,千万别怀疑自己智商,学习过程都是这样的,大家智商都差不多,哈哈。
|
||||
所以初学者刚开始学习算法的时候,看到简单题目没有思路很正常,千万别怀疑自己智商,学习过程都是这样的,大家智商都差不多。
|
||||
|
||||
只要把基本类型的题目都做过,总结过之后,思路自然就开阔了。
|
||||
只要把基本类型的题目都做过,总结过之后,思路自然就开阔了,加油💪
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
@ -300,7 +300,7 @@ public:
|
||||
|
||||
所以本题应该是一道hard题目了。
|
||||
|
||||
**可能刷过这道题目的录友都没感受到自己原来克服了这么多难点,就把这道题目AC了**,这应该叫做无招胜有招,人码合一,哈哈哈。
|
||||
**可能刷过这道题目的录友都没感受到自己原来克服了这么多难点,就把这道题目AC了**,这应该叫做无招胜有招,人码合一。
|
||||
|
||||
|
||||
|
||||
|
@ -187,7 +187,7 @@ public:
|
||||
|
||||
## 总结
|
||||
|
||||
这次可以说把环形链表这道题目的各个细节,完完整整的证明了一遍,说这是全网最详细讲解不为过吧,哈哈。
|
||||
这次可以说把环形链表这道题目的各个细节,完完整整的证明了一遍,说这是全网最详细讲解不为过吧。
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
@ -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"/>
|
||||
|
@ -279,6 +279,42 @@ class Solution:
|
||||
return result
|
||||
```
|
||||
|
||||
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"/>
|
||||
|
@ -111,7 +111,7 @@ public:
|
||||
}
|
||||
};
|
||||
```
|
||||
* 时间复杂度: push为O(n),其他为O(1)
|
||||
* 时间复杂度: pop为O(n),其他为O(1)
|
||||
* 空间复杂度: O(n)
|
||||
|
||||
## 优化
|
||||
@ -158,7 +158,7 @@ public:
|
||||
}
|
||||
};
|
||||
```
|
||||
* 时间复杂度: push为O(n),其他为O(1)
|
||||
* 时间复杂度: pop为O(n),其他为O(1)
|
||||
* 空间复杂度: O(n)
|
||||
|
||||
|
||||
|
@ -127,7 +127,7 @@ public:
|
||||
|
||||
工作中如果发现某一个功能自己要经常用,同事们可能也会用到,自己就花点时间把这个功能抽象成一个好用的函数或者工具类,不仅自己方便,也方便了同事们。
|
||||
|
||||
同事们就会逐渐认可你的工作态度和工作能力,自己的口碑都是这么一点一点积累起来的!在同事圈里口碑起来了之后,你就发现自己走上了一个正循环,以后的升职加薪才少不了你!哈哈哈
|
||||
同事们就会逐渐认可你的工作态度和工作能力,自己的口碑都是这么一点一点积累起来的!在同事圈里口碑起来了之后,你就发现自己走上了一个正循环,以后的升职加薪才少不了你!
|
||||
|
||||
|
||||
|
||||
|
@ -156,7 +156,7 @@ public:
|
||||
|
||||
但如果没有按照「代码随想录」的题目顺序来做的话,做动态规划或者做背包问题,上来就做这道题,那还是挺难的!
|
||||
|
||||
经过前面的训练这道题已经是简单题了,哈哈哈
|
||||
经过前面的训练这道题已经是简单题了
|
||||
|
||||
|
||||
|
||||
|
@ -169,7 +169,7 @@ public:
|
||||
|
||||
这也是大多数同学学习动态规划的苦恼所在,有的时候递推公式很简单,难在遍历顺序上!
|
||||
|
||||
但最终又可以稀里糊涂的把题目过了,也不知道为什么这样可以过,反正就是过了,哈哈
|
||||
但最终又可以稀里糊涂的把题目过了,也不知道为什么这样可以过,反正就是过了。
|
||||
|
||||
那么这篇文章就把遍历顺序分析的清清楚楚。
|
||||
|
||||
|
@ -345,6 +345,79 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
/* 该方法是对第二个方法的改进,主要变化在于将某点的所有终点变更为链表的形式,优点在于
|
||||
1.添加终点时直接在对应位置添加节点,避免了TreeMap增元素时的频繁调整
|
||||
2.同时每次对终点进行增加删除查找时直接通过下标操作,避免hashMap反复计算hash*/
|
||||
class Solution {
|
||||
//key为起点,value是有序的终点的列表
|
||||
Map<String, LinkedList<String>> ticketMap = new HashMap<>();
|
||||
LinkedList<String> result = new LinkedList<>();
|
||||
int total;
|
||||
|
||||
public List<String> findItinerary(List<List<String>> tickets) {
|
||||
total = tickets.size() + 1;
|
||||
//遍历tickets,存入ticketMap中
|
||||
for (List<String> ticket : tickets) {
|
||||
addNew(ticket.get(0), ticket.get(1));
|
||||
}
|
||||
deal("JFK");
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean deal(String currentLocation) {
|
||||
result.add(currentLocation);
|
||||
//机票全部用完,找到最小字符路径
|
||||
if (result.size() == total) {
|
||||
return true;
|
||||
}
|
||||
//当前位置的终点列表
|
||||
LinkedList<String> targetLocations = ticketMap.get(currentLocation);
|
||||
//没有从当前位置出发的机票了,说明这条路走不通
|
||||
if (targetLocations != null && !targetLocations.isEmpty()) {
|
||||
//终点列表中遍历到的终点
|
||||
String targetLocation;
|
||||
//遍历从当前位置出发的机票
|
||||
for (int i = 0; i < targetLocations.size(); i++) {
|
||||
targetLocation = targetLocations.get(i);
|
||||
//删除终点列表中当前的终点
|
||||
targetLocations.remove(i);
|
||||
//递归
|
||||
if (deal(targetLocation)) {
|
||||
return true;
|
||||
}
|
||||
//路线走不通,将机票重新加回去
|
||||
targetLocations.add(i, targetLocation);
|
||||
result.removeLast();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在map中按照字典顺序添加新元素
|
||||
*
|
||||
* @param start 起点
|
||||
* @param end 终点
|
||||
*/
|
||||
void addNew(String start, String end) {
|
||||
LinkedList<String> startAllEnd = ticketMap.getOrDefault(start, new LinkedList<>());
|
||||
if (!startAllEnd.isEmpty()) {
|
||||
for (int i = 0; i < startAllEnd.size(); i++) {
|
||||
if (end.compareTo(startAllEnd.get(i)) < 0) {
|
||||
startAllEnd.add(i, end);
|
||||
return;
|
||||
}
|
||||
}
|
||||
startAllEnd.add(startAllEnd.size(), end);
|
||||
} else {
|
||||
startAllEnd.add(end);
|
||||
ticketMap.put(start, startAllEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python
|
||||
回溯 使用used数组
|
||||
|
||||
|
@ -216,7 +216,7 @@ public:
|
||||
|
||||
只不过平时我们习惯了在一维数组或者二维数组上推导公式,一下子换成了树,就需要对树的遍历方式足够了解!
|
||||
|
||||
大家还记不记得我在讲解贪心专题的时候,讲到这道题目:[贪心算法:我要监控二叉树!](https://programmercarl.com/0968.监控二叉树.html),这也是贪心算法在树上的应用。**那我也可以把这个算法起一个名字,叫做树形贪心**,哈哈哈
|
||||
大家还记不记得我在讲解贪心专题的时候,讲到这道题目:[贪心算法:我要监控二叉树!](https://programmercarl.com/0968.监控二叉树.html),这也是贪心算法在树上的应用。**那我也可以把这个算法起一个名字,叫做树形贪心**。
|
||||
|
||||
“树形贪心”词汇从此诞生,来自「代码随想录」
|
||||
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
## 其他语言版本
|
||||
|
||||
### Java:
|
||||
|
||||
版本一:使用HashSet
|
||||
```Java
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@ -159,7 +159,28 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
版本二:使用Hash數組
|
||||
```java
|
||||
class Solution {
|
||||
public int[] intersection(int[] nums1, int[] nums2) {
|
||||
int[] hash1 = new int[1002];
|
||||
int[] hash2 = new int[1002];
|
||||
for(int i : nums1)
|
||||
hash1[i]++;
|
||||
for(int i : nums2)
|
||||
hash2[i]++;
|
||||
List<Integer> resList = new ArrayList<>();
|
||||
for(int i = 0; i < 1002; i++)
|
||||
if(hash1[i] > 0 && hash2[i] > 0)
|
||||
resList.add(i);
|
||||
int index = 0;
|
||||
int res[] = new int[resList.size()];
|
||||
for(int i : resList)
|
||||
res[index++] = i;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
### Python3:
|
||||
(版本一) 使用字典和集合
|
||||
|
||||
|
@ -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. 摆动序列
|
||||
|
||||
|
@ -10,6 +10,37 @@
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/island-perimeter/)
|
||||
|
||||
给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。
|
||||
|
||||
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
|
||||
|
||||
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
|
||||
|
||||
|
||||

|
||||
|
||||
* 输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
|
||||
* 输出:16
|
||||
* 解释:它的周长是上面图片中的 16 个黄色的边
|
||||
|
||||
|
||||
示例 2:
|
||||
|
||||
* 输入:grid = [[1]]
|
||||
* 输出:4
|
||||
|
||||
示例 3:
|
||||
|
||||
* 输入:grid = [[1,0]]
|
||||
* 输出:4
|
||||
|
||||
提示:
|
||||
|
||||
* row == grid.length
|
||||
* col == grid[i].length
|
||||
* 1 <= row, col <= 100
|
||||
* grid[i][j] 为 0 或 1
|
||||
|
||||
## 思路
|
||||
|
||||
岛屿问题最容易让人想到BFS或者DFS,但是这道题还真的没有必要,别把简单问题搞复杂了。
|
||||
|
@ -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)的录友,看到这道题,应该有一种直觉,就是感觉好像回溯法可以爆搜出来。
|
||||
|
||||
事实确实如此,下面我也会给出相应的代码,只不过会超时,哈哈。
|
||||
事实确实如此,下面我也会给出相应的代码,只不过会超时。
|
||||
|
||||
这道题目咋眼一看和动态规划背包啥的也没啥关系。
|
||||
|
||||
|
@ -396,25 +396,33 @@ function nextGreaterElement(nums1: number[], nums2: number[]): number[] {
|
||||
### Rust
|
||||
|
||||
```rust
|
||||
use std::collections::HashMap;
|
||||
impl Solution {
|
||||
pub fn next_greater_element(nums1: Vec<i32>, nums2: Vec<i32>) -> Vec<i32> {
|
||||
let mut ans = vec![-1; nums1.len()];
|
||||
use std::collections::HashMap;
|
||||
let mut map = HashMap::new();
|
||||
for (idx, &i) in nums1.iter().enumerate() {
|
||||
map.insert(i, idx);
|
||||
let (mut res, mut map) = (vec![-1; nums1.len()], HashMap::new());
|
||||
if nums1.is_empty() {
|
||||
return res;
|
||||
}
|
||||
|
||||
nums1.into_iter().enumerate().for_each(|(v, k)| {
|
||||
map.insert(k, v);
|
||||
});
|
||||
|
||||
let mut stack = vec![];
|
||||
for (idx, &i) in nums2.iter().enumerate() {
|
||||
while !stack.is_empty() && nums2[*stack.last().unwrap()] < i {
|
||||
let pos = stack.pop().unwrap();
|
||||
if let Some(&jdx) = map.get(&nums2[pos]) {
|
||||
ans[jdx] = i;
|
||||
for (i, &value) in nums2.iter().enumerate() {
|
||||
while let Some(&top) = stack.last() {
|
||||
if value <= nums2[top] {
|
||||
break;
|
||||
}
|
||||
let stacked_index = stack.pop().unwrap();
|
||||
if let Some(&mapped_index) = map.get(&nums2[stacked_index]) {
|
||||
res[mapped_index] = value;
|
||||
}
|
||||
}
|
||||
stack.push(idx);
|
||||
stack.push(i);
|
||||
}
|
||||
ans
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -280,7 +280,7 @@ public:
|
||||
* [二叉树:前中后序迭代法](https://programmercarl.com/二叉树的迭代遍历.html)
|
||||
* [二叉树:前中后序统一风格的迭代方式](https://programmercarl.com/二叉树的统一迭代法.html)
|
||||
|
||||
下面我给出其中的一种中序遍历的迭代法,其中间处理逻辑一点都没有变(我从递归法直接粘过来的代码,连注释都没改,哈哈)
|
||||
下面我给出其中的一种中序遍历的迭代法,其中间处理逻辑一点都没有变(我从递归法直接粘过来的代码,连注释都没改)
|
||||
|
||||
代码如下:
|
||||
|
||||
|
@ -293,6 +293,28 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
> 版本二:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn next_greater_elements(nums: Vec<i32>) -> Vec<i32> {
|
||||
let (mut stack, mut res) = (vec![], vec![-1; nums.len()]);
|
||||
|
||||
for i in 0..nums.len() * 2 {
|
||||
while let Some(&top) = stack.last() {
|
||||
if nums[i % nums.len()] <= nums[top] {
|
||||
break;
|
||||
}
|
||||
let saved_index = stack.pop().unwrap();
|
||||
res[saved_index] = nums[i % nums.len()];
|
||||
}
|
||||
stack.push(i % nums.len());
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
@ -184,7 +184,7 @@ public:
|
||||
* 空间复杂度: O(m)
|
||||
|
||||
|
||||
是不是发现代码如此精简,哈哈
|
||||
是不是发现代码如此精简
|
||||
|
||||
## 总结
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
## 思路
|
||||
|
||||
这道题目还是挺简单的,大家不要想复杂了,一波哈希法又一波图论算法啥的,哈哈。
|
||||
这道题目还是挺简单的,大家不要想复杂了,一波哈希法又一波图论算法之类的。
|
||||
|
||||
其实就是,x,y坐标,初始为0,然后:
|
||||
* if (moves[i] == 'U') y++;
|
||||
|
@ -82,7 +82,7 @@ if (root == NULL) {
|
||||
|
||||
此时要明确,需要遍历整棵树么?
|
||||
|
||||
别忘了这是搜索树,遍历整棵搜索树简直是对搜索树的侮辱,哈哈。
|
||||
别忘了这是搜索树,遍历整棵搜索树简直是对搜索树的侮辱。
|
||||
|
||||
搜索树是有方向了,可以根据插入元素的数值,决定递归方向。
|
||||
|
||||
|
@ -217,7 +217,29 @@ class Solution:
|
||||
self.path.pop() # 回溯
|
||||
```
|
||||
|
||||
### 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">
|
||||
|
@ -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)
|
||||
|
||||
是不是发现这代码也太简单了,哈哈。
|
||||
是不是发现这代码也太简单了。
|
||||
|
||||
## 总结
|
||||
|
||||
|
@ -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)也没那么难了,传说已经不是传说了。
|
||||
|
||||
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
|
||||
# 并查集理论基础
|
||||
|
||||
图论中,关于深搜和广搜我们在这里:[钥匙和房间](https://mp.weixin.qq.com/s/E9NlJy9PW1oJuD8N2EURoQ) 已经更新完毕了。
|
||||
|
||||
接下来我们来讲一下并查集,首先当然是并查集理论基础。
|
||||
|
||||
## 背景
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
# 广度优先搜索理论基础
|
||||
|
||||
> 号外!!代码随想录图论内容已经计划开更了!
|
||||
|
||||
在[深度优先搜索](https://programmercarl.com/图论深搜理论基础.html)的讲解中,我们就讲过深度优先搜索和广度优先搜索的区别。
|
||||
|
||||
|
@ -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个人认为:如果找出局部最优并可以推出全局最优,就是
|
||||
|
||||
周总结里会对每周的题目中大家的疑问、相关难点或者笔误之类的进行复盘和总结。
|
||||
|
||||
如果大家发现文章哪里有问题,那么在周总结里或者文章评论区一定进行了修正,保证不会因为我的笔误或者理解问题而误导大家,哈哈。
|
||||
如果大家发现文章哪里有问题,那么在周总结里或者文章评论区一定进行了修正,保证不会因为我的笔误或者理解问题而误导大家。
|
||||
|
||||
所以周总结一定要看!
|
||||
|
||||
|
Reference in New Issue
Block a user