Merge branch 'youngyangyang04:master' into master

This commit is contained in:
Xin Li
2023-09-04 04:00:46 -07:00
committed by GitHub
42 changed files with 504 additions and 59 deletions

View File

@ -37,20 +37,20 @@
[242. 有效的字母异位词](https://www.programmercarl.com/0242.有效的字母异位词.html) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://www.programmercarl.com/0349.两个数组的交集.html)这道题目是通过set作为哈希表来解决哈希问题。
首先我强调一下 **什么时候使用哈希法**,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
首先我强调一下 **什么时候使用哈希法**,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
本题呢,我就需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。
那么我们就应该想到使用哈希法了。
因为本,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,**需要使用 key value结构来存放key来存元素value来存下标那么使用map正合适**。
因为本,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,**需要使用 key value结构来存放key来存元素value来存下标那么使用map正合适**。
再来看一下使用数组和set来做哈希法的局限。
* 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
* set是一个集合里面放的元素只能是一个key而两数之和这道题目不仅要判断y是否存在而且还要记录y的下标位置因为要返回x 和 y的下标。所以set 也不能用。
此时就要选择另一种数据结构map map是一种key value的存储结构可以用key保存数值用value保存数值所在的下标。
此时就要选择另一种数据结构map map是一种key value的存储结构可以用key保存数值用value保存数值所在的下标。
C++中map有三种类型

View File

@ -171,7 +171,7 @@ public:
#### a的去重
去重其实主要考虑三个数的去重 a, b ,c, 对应的就是 nums[i]nums[left]nums[right]
去重其实主要考虑三个数的去重 a, b ,c, 对应的就是 nums[i]nums[left]nums[right]
a 如果重复了怎么办a是nums里遍历的元素那么应该直接跳过去
@ -181,7 +181,7 @@ a 如果重复了怎么办a是nums里遍历的元素那么应该直接跳
其实不一样
都是和 nums[i]进行比较是比较它的前一个还是比较的后一个
都是和 nums[i]进行比较是比较它的前一个还是比较的后一个
如果我们的写法是 这样
@ -191,7 +191,7 @@ if (nums[i] == nums[i + 1]) { // 去重操作
}
```
我们就把 三元组中出现重复元素的情况直接pass掉了。 例如{-1, -1 ,2} 这组数据,当遍历到第一个-1 的时候,判断 下一个也是-1那这组数据就pass了。
那我们就把 三元组中出现重复元素的情况直接pass掉了。 例如{-1, -1 ,2} 这组数据,当遍历到第一个-1 的时候,判断 下一个也是-1那这组数据就pass了。
**我们要做的是 不能有重复的三元组,但三元组内的元素是可以重复的!**

View File

@ -649,6 +649,54 @@ object Solution {
}
}
```
### Ruby:
```ruby
def four_sum(nums, target)
#结果集
result = []
nums = nums.sort!
for i in 0..nums.size - 1
return result if i > 0 && nums[i] > target && nums[i] >= 0
#对a进行去重
next if i > 0 && nums[i] == nums[i - 1]
for j in i + 1..nums.size - 1
break if nums[i] + nums[j] > target && nums[i] + nums[j] >= 0
#对b进行去重
next if j > i + 1 && nums[j] == nums[j - 1]
left = j + 1
right = nums.size - 1
while left < right
sum = nums[i] + nums[j] + nums[left] + nums[right]
if sum > target
right -= 1
elsif sum < target
left += 1
else
result << [nums[i], nums[j], nums[left], nums[right]]
#对c进行去重
while left < right && nums[left] == nums[left + 1]
left += 1
end
#对d进行去重
while left < right && nums[right] == nums[right - 1]
right -= 1
end
right -= 1
left += 1
end
end
end
end
return result
end
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -444,4 +444,3 @@ public class Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -27,16 +27,16 @@
 needle 是空字符串时我们应当返回什么值呢这是一个在面试中很好的问题。
对于本题而言 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
## 算法公开课
## 思路
本题是KMP 经典题目。
以下文字如果看不进去可以看我的B站视频
本题是KMP 经典题目。以下文字如果看不进去,可以看[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html),相信结合视频再看本篇题解,更有助于大家对本题的理解。
* [帮你把KMP算法学个通透B站理论篇](https://www.bilibili.com/video/BV1PD4y1o7nd/)
* [帮你把KMP算法学个通透求next数组代码篇](https://www.bilibili.com/video/BV1M5411j7Xx)
## 思路
KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。**
本篇将以如下顺序来讲解KMP
@ -1362,3 +1362,4 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -28,6 +28,10 @@
* 输入height = [4,2,0,3,2,5]
* 输出9
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[单调栈经典来袭LeetCode:42.接雨水](https://www.bilibili.com/video/BV1uD4y1u75P/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@ -1029,4 +1033,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -469,4 +469,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -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:
@ -744,4 +741,3 @@ end
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -559,3 +559,4 @@ public class Solution
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -739,3 +739,4 @@ object Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -20,6 +20,10 @@
* 1 <= heights.length <=10^5
* 0 <= heights[i] <= 10^4
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[单调栈,又一次经典来袭! LeetCode84.柱状图中最大的矩形](https://www.bilibili.com/video/BV1Ns4y1o7uB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
本题和[42. 接雨水](https://programmercarl.com/0042.接雨水.html),是遥相呼应的两道题目,建议都要仔细做一做,原理上有很多相同的地方,但细节上又有差异,更可以加深对单调栈的理解!

View File

@ -18,7 +18,7 @@
* [102.二叉树的层序遍历](https://leetcode.cn/problems/binary-tree-level-order-traversal/)
* [107.二叉树的层次遍历II](https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/)
* [199.二叉树的右视图](https://leetcode.cn/problems/binary-tree-right-side-view/)
* [637.二叉树的层平均值](https://leetcode.cn/problems/binary-tree-right-side-view/)
* [637.二叉树的层平均值](https://leetcode.cn/problems/average-of-levels-in-binary-tree/)
* [429.N叉树的层序遍历](https://leetcode.cn/problems/n-ary-tree-level-order-traversal/)
* [515.在每个树行中找最大值](https://leetcode.cn/problems/find-largest-value-in-each-tree-row/)
* [116.填充每个节点的下一个右侧节点指针](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/)

View File

@ -21,6 +21,9 @@
* 0 <= s.length, t.length <= 1000
* s 和 t 由英文字母组成
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[动态规划之子序列,为了编辑距离做铺垫 | LeetCode115.不同的子序列](https://www.bilibili.com/video/BV1fG4y1m75Q/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路

View File

@ -385,6 +385,55 @@ class Solution {
}
}
```
### Python3
```Python
// 深度优先遍历
class Solution:
dir_list = [(0, 1), (0, -1), (1, 0), (-1, 0)]
def solve(self, board: List[List[str]]) -> None:
"""
Do not return anything, modify board in-place instead.
"""
row_size = len(board)
column_size = len(board[0])
visited = [[False] * column_size for _ in range(row_size)]
# 从边缘开始将边缘相连的O改成A。然后遍历所有将A改成OO改成X
# 第一行和最后一行
for i in range(column_size):
if board[0][i] == "O" and not visited[0][i]:
self.dfs(board, 0, i, visited)
if board[row_size-1][i] == "O" and not visited[row_size-1][i]:
self.dfs(board, row_size-1, i, visited)
# 第一列和最后一列
for i in range(1, row_size-1):
if board[i][0] == "O" and not visited[i][0]:
self.dfs(board, i, 0, visited)
if board[i][column_size-1] == "O" and not visited[i][column_size-1]:
self.dfs(board, i, column_size-1, visited)
for i in range(row_size):
for j in range(column_size):
if board[i][j] == "A":
board[i][j] = "O"
elif board[i][j] == "O":
board[i][j] = "X"
def dfs(self, board, x, y, visited):
if visited[x][y] or board[x][y] == "X":
return
visited[x][y] = True
board[x][y] = "A"
for i in range(4):
new_x = x + self.dir_list[i][0]
new_y = y + self.dir_list[i][1]
if new_x >= len(board) or new_y >= len(board[0]) or new_x < 0 or new_y < 0:
continue
self.dfs(board, new_x, new_y, visited)
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -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"/>

View File

@ -563,4 +563,3 @@ public class Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -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)

View File

@ -133,7 +133,7 @@ left与right的逻辑处理; // 中
![236.二叉树的最近公共祖先](https://code-thinking-1253855093.file.myqcloud.com/pics/2021020415105872.png)
就像图中一样直接返回7,多美滋滋
就像图中一样直接返回7。
但事实上还要遍历根节点右子树即使此时已经找到了目标节点了也就是图中的节点4、15、20。

View File

@ -237,13 +237,10 @@ public:
```cpp
for (pair<const string, int>& target : targets[result[result.size() - 1]])
```
pair里要有const因为map中的key是不可修改的所以是`pair<const string, int>`
如果不加const也可以复制一份pair例如这么写
一定要加上引用即 `& target`,因为后面有对 target.second 做减减操作,如果没有引用,单纯复制,这个结果就没记录下来,那最后的结果就不对了。
```cpp
for (pair<string, int>target : targets[result[result.size() - 1]])
```
加上引用之后,就必须在 string 前面加上 const因为map中的key 是不可修改了,这就是语法规定了。
## 总结
@ -348,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数组

View File

@ -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
(版本一) 使用字典和集合

View File

@ -4,6 +4,7 @@
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 416. 分割等和子集
[力扣题目链接](https://leetcode.cn/problems/partition-equal-subset-sum/)
@ -730,3 +731,4 @@ object Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -41,7 +41,7 @@
## 思路
本题眼一看好像和[0015.三数之和](https://programmercarl.com/0015.三数之和.html)[0018.四数之和](https://programmercarl.com/0018.四数之和.html)差不多,其实差很多。
本题眼一看好像和[0015.三数之和](https://programmercarl.com/0015.三数之和.html)[0018.四数之和](https://programmercarl.com/0018.四数之和.html)差不多,其实差很多。
**本题是使用哈希法的经典题目,而[0015.三数之和](https://programmercarl.com/0015.三数之和.html)[0018.四数之和](https://programmercarl.com/0018.四数之和.html)并不合适使用哈希法**,因为三数之和和四数之和这两道题目使用哈希法在不超时的情况下做到对结果去重是很困难的,很有多细节需要处理。

View File

@ -52,7 +52,7 @@
也就是由前后相同的子串组成。
那么既然前面有相同的子串,后面有相同的子串,用 s + s这样组成的字符串中后面的子串做前串的子串做后串就一定还能组成一个s如图
那么既然前面有相同的子串,后面有相同的子串,用 s + s这样组成的字符串中后面的子串做前串的子串做后串就一定还能组成一个s如图
![图二](https://code-thinking-1253855093.file.myqcloud.com/pics/20220728104931.png)

View File

@ -10,6 +10,37 @@
[力扣题目链接](https://leetcode.cn/problems/island-perimeter/)
给定一个 row x col 的二维网格地图 grid 其中grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230829180848.png)
* 输入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但是这道题还真的没有必要别把简单问题搞复杂了。

View File

@ -37,6 +37,10 @@ nums1 中数字 x 的下一个更大元素是指 x  nums2 中对应位
* nums1和nums2中所有整数 互不相同
* nums1 中的所有整数同样出现在 nums2 中
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[单调栈,套上一个壳子就有点绕了| LeetCode:496.下一个更大元素](https://www.bilibili.com/video/BV1jA411m7dX/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
做本题之前,建议先做一下[739. 每日温度](https://programmercarl.com/0739.每日温度.html)
@ -392,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
}
}
```

View File

@ -21,6 +21,10 @@
* 1 <= nums.length <= 10^4
* -10^9 <= nums[i] <= 10^9
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[单调栈成环了可怎么办LeetCode503.下一个更大元素II](https://www.bilibili.com/video/BV15y4y1o7Dw/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
@ -289,8 +293,31 @@ 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">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -27,6 +27,10 @@
* 1 <= s.length <= 1000
* s 只包含小写英文字母
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[动态规划再显神通LeetCode516.最长回文子序列](https://www.bilibili.com/video/BV1d8411K7W6/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路

View File

@ -26,6 +26,10 @@
提示:输入的字符串长度不会超过 1000 。
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[动态规划字符串性质决定了DP数组的定义 | LeetCode647.回文子串](https://www.bilibili.com/video/BV17G4y1y7z9/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路
### 暴力解法
@ -571,4 +575,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -697,4 +697,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -17,6 +17,10 @@
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[单调栈你该了解的这里都讲了LeetCode:739.每日温度](https://www.bilibili.com/video/BV1my4y1Z7jj/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
## 思路

View File

@ -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">

View File

@ -30,7 +30,7 @@
### 暴力排序
最直观的想法,莫过于:每个数平方之后,排个序,美滋滋,代码如下:
最直观的想法,莫过于:每个数平方之后,排个序,代码如下:
```CPP
class Solution {

View File

@ -475,6 +475,26 @@ impl Solution {
}
```
### Ruby
```ruby
def remove_duplicates(s)
#数组模拟栈
stack = []
s.each_char do |chr|
if stack.empty?
stack.push chr
else
head = stack.pop
#重新进栈
stack.push head, chr if head != chr
end
end
return stack.join
end
```
<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>

89
problems/qita/acm.md Normal file
View File

@ -0,0 +1,89 @@
# 如何练习ACM模式输入输入模式 | 如何准备笔试 | 卡码网
卡码网地址:[https://kamacoder.com](https://kamacoder.com)
## 为什么卡码网
录友们在求职的时候会发现很多公司的笔试题和面试题都是ACM模式 而大家习惯去力扣刷题,力扣是核心代码模式。
当大家在做ACM模式的算法题的时候需要自己处理数据的输入输出**如果没有接触过的话,还是挺难的**。
[知识星球](https://programmercarl.com/other/kstar.html)里很多录友的日常打卡中,都表示被 ACM模式折磨过
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230727163624.png' width=500 alt=''></img></div>
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230727163938.png' width=500 alt=''></img></div>
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230727164042.png' width=500 alt=''></img></div>
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230727164151.png' width=500 alt=''></img></div>
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230727164459.png' width=500 alt=''></img></div>
所以我正式推出:**卡码网**[https://kamacoder.com](https://kamacoder.com)**专门帮助大家练习ACM模式**。
那么之前大家去哪里练习ACM模式呢
去牛客做笔试真题,结果发现 ACM模式没练出来题目倒是巨难一点思路都没有代码更没有写ACM模式无从练起。
去洛谷POJ上练习 结果发现 题目超多,不知道从哪里开始刷,也没有一个循序渐进的刷题顺序。
**而卡码网上有我精选+制作的25道题目**我还把25题的后台测试数据制作了一遍保证大家练习的效果。
为什么题目不多只有25道
因为大家练习ACM模式不需要那么多题目有一个循序渐进的练习过程就好了。
这25道题目包含了数组、链表、哈希表、字符串、二叉树、动态规划以及图的的题目常见的输入输出方式都覆盖了。
**这是最精华的25道题目**!。
## 卡码网长什么样
来看看这极简的界面,没有烂七八糟的功能,只有刷题!
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230727171535.png' width=500 alt=''></img></div>
在「状态」这里可以看到 大家提交的代码和判题记录,目前卡码网([https://kamacoder.com](https://kamacoder.com))几乎无时无刻都有卡友在提交代码。
看看大家周六晚上都在做什么,刷哪些题目。
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230730200451.png' width=500 alt=''></img></div>
提交代码的界面是这样的,**目前支持所有主流刷题语言**。
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230727172727.png' width=500 alt=''></img></div>
## 题解
基本大家来卡码网([https://kamacoder.com](https://kamacoder.com)练习ACM模式都是对输入输出不够了解的所以想看现成的题解看看究竟是怎么处理的。
所以我用C++把卡码网上25道题目的题解都写了并发布到Github上
[https://github.com/youngyangyang04/kamacoder-solutions](https://github.com/youngyangyang04/kamacoder-solutions)
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230730200709.png' width=500 alt=''></img></div>
**欢迎去Github上star欢迎fork也欢迎来Github仓库贡献其他语言版本成为contributor**
如果不懂如何和开源项目提交代码,[可以看这里](https://www.programmercarl.com/qita/join.html)
目前已经有两位录友贡献C和Java版本了。
<div align="center"><img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20230730195613.png' width=500 alt=''></img></div>
期待在Githubhttps://github.com/youngyangyang04/kamacoder-solutions 的contributors上也出现你的头像。
目前题解只有C++代码吗?
当然不是,大多数题目已经有了 Java、python、C版本。 **其他语言版本就给录友们成为contributor的机会了**
## 最后
卡码网地址:[https://kamacoder.com](https://kamacoder.com)
快去体验吧,笔试之前最好 把卡码网25道题目都刷完。
期待录友们成为最早一批把卡码网刷爆的coder

View File

@ -163,4 +163,3 @@
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -150,7 +150,7 @@
最后再说一说二叉树中深度优先和广度优先遍历实现方式,我们做二叉树相关题目,经常会使用递归的方式来实现深度优先遍历,也就是实现前中后序遍历,使用递归是比较方便的。
**之前我们讲栈与队列的时候,就说过栈其实就是递归的一种实现结构**,也就说前中后序遍历的逻辑其实都是可以借助栈使用递归的方式来实现的。
**之前我们讲栈与队列的时候,就说过栈其实就是递归的一种实现结构**,也就说前中后序遍历的逻辑其实都是可以借助栈使用递归的方式来实现的。
而广度优先遍历的实现一般使用队列来实现,这也是队列先进先出的特点所决定的,因为需要先进先出的结构,才能一层一层的来遍历二叉树。

View File

@ -1,8 +1,6 @@
# 并查集理论基础
图论中,关于深搜和广搜我们在这里:[钥匙和房间](https://mp.weixin.qq.com/s/E9NlJy9PW1oJuD8N2EURoQ) 已经更新完毕了。
接下来我们来讲一下并查集,首先当然是并查集理论基础。
## 背景

View File

@ -6,7 +6,6 @@
# 广度优先搜索理论基础
> 号外!!代码随想录图论内容已经计划开更了!
在[深度优先搜索](https://programmercarl.com/图论深搜理论基础.html)的讲解中,我们就讲过深度优先搜索和广度优先搜索的区别。

View File

@ -128,4 +128,3 @@ KMP算法是字符串查找最重要的算法但彻底理解KMP并不容易
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -28,7 +28,7 @@
![416.分割等和子集1](https://code-thinking-1253855093.file.myqcloud.com/pics/20210117171307407.png)
至于背包九讲其他背包面试几乎不会问都是竞赛级别的了leetcode上连多重背包的题目都没有所以题库也告诉我们01背包和完全背包就够用了。
至于背包九讲其他背包面试几乎不会问都是竞赛级别的了leetcode上连多重背包的题目都没有所以题库也告诉我们01背包和完全背包就够用了。
而完全背包又是也是01背包稍作变化而来完全背包的物品数量是无限的。

View File

@ -11,6 +11,9 @@
<img src='https://code-thinking-1253855093.file.myqcloud.com/pics/20210917104315.png' width=600 alt='贪心算法大纲'> </img></div>
## 算法公开课
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[贪心算法理论基础!](https://www.bilibili.com/video/BV1WK4y1R71x/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 什么是贪心

View File

@ -508,4 +508,3 @@ object Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>