mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 19:44:45 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -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,有三种类型:
|
||||
|
||||
@ -318,7 +318,7 @@ function twoSum(nums: number[], target: number): number[] {
|
||||
};
|
||||
```
|
||||
|
||||
### php:
|
||||
### PhP:
|
||||
|
||||
```php
|
||||
function twoSum(array $nums, int $target): array
|
||||
@ -501,3 +501,4 @@ int* twoSum(int* nums, int numsSize, int target, int* returnSize){
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -152,10 +152,10 @@ public:
|
||||
|
||||
## 相关题目推荐
|
||||
|
||||
* 26.删除排序数组中的重复项
|
||||
* 283.移动零
|
||||
* 844.比较含退格的字符串
|
||||
* 977.有序数组的平方
|
||||
* [26.删除排序数组中的重复项](https://leetcode.cn/problems/remove-duplicates-from-sorted-array/)
|
||||
* [283.移动零](https://leetcode.cn/problems/move-zeroes/)
|
||||
* [844.比较含退格的字符串](https://leetcode.cn/problems/backspace-string-compare/)
|
||||
* [977.有序数组的平方](https://leetcode.cn/problems/squares-of-a-sorted-array/)
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
@ -444,3 +444,4 @@ public class Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -73,7 +73,7 @@ candidates 中的数字可以无限制重复被选取。
|
||||
|
||||
如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:[17.电话号码的字母组合](https://programmercarl.com/0017.电话号码的字母组合.html)
|
||||
|
||||
**注意以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路,后面我再讲解排列的时候就重点介绍**。
|
||||
**注意以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路,后面我在讲解排列的时候会重点介绍**。
|
||||
|
||||
代码如下:
|
||||
|
||||
@ -311,7 +311,7 @@ class Solution:
|
||||
|
||||
for i in range(startIndex, len(candidates)):
|
||||
if total + candidates[i] > target:
|
||||
break
|
||||
continue
|
||||
total += candidates[i]
|
||||
path.append(candidates[i])
|
||||
self.backtracking(candidates, target, total, i, path, result)
|
||||
|
@ -16,11 +16,13 @@
|
||||
- 输出: 6
|
||||
- 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
|
||||
|
||||
# 视频讲解
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和](https://www.bilibili.com/video/BV1aY4y1Z7ya),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和](https://www.bilibili.com/video/BV1aY4y1Z7ya),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
## 暴力解法
|
||||
## 思路
|
||||
|
||||
### 暴力解法
|
||||
|
||||
暴力解法的思路,第一层 for 就是设置起始位置,第二层 for 循环遍历数组寻找最大值
|
||||
|
||||
@ -48,7 +50,7 @@ public:
|
||||
|
||||
以上暴力的解法 C++勉强可以过,其他语言就不确定了。
|
||||
|
||||
## 贪心解法
|
||||
### 贪心解法
|
||||
|
||||
**贪心贪的是哪里呢?**
|
||||
|
||||
@ -104,7 +106,7 @@ public:
|
||||
|
||||
当然题目没有说如果数组为空,应该返回什么,所以数组为空的话返回啥都可以了。
|
||||
|
||||
## 常见误区
|
||||
### 常见误区
|
||||
|
||||
误区一:
|
||||
|
||||
@ -122,7 +124,7 @@ public:
|
||||
|
||||
其实并不会,因为还有一个变量 result 一直在更新 最大的连续和,只要有更大的连续和出现,result 就更新了,那么 result 已经把 4 更新了,后面 连续和变成 3,也不会对最后结果有影响。
|
||||
|
||||
## 动态规划
|
||||
### 动态规划
|
||||
|
||||
当然本题还可以用动态规划来做,在代码随想录动态规划章节我会详细介绍,如果大家想在想看,可以直接跳转:[动态规划版本详解](https://programmercarl.com/0053.%E6%9C%80%E5%A4%A7%E5%AD%90%E5%BA%8F%E5%92%8C%EF%BC%88%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%EF%BC%89.html#%E6%80%9D%E8%B7%AF)
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
|
||||
## 54.螺旋矩阵
|
||||
# 54.螺旋矩阵
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/spiral-matrix/)
|
||||
|
||||
@ -200,6 +200,58 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### Javascript
|
||||
```
|
||||
/**
|
||||
* @param {number[][]} matrix
|
||||
* @return {number[]}
|
||||
*/
|
||||
var spiralOrder = function(matrix) {
|
||||
let m = matrix.length
|
||||
let n = matrix[0].length
|
||||
|
||||
let startX = startY = 0
|
||||
let i = 0
|
||||
let arr = new Array(m*n).fill(0)
|
||||
let offset = 1
|
||||
let loop = mid = Math.floor(Math.min(m,n) / 2)
|
||||
while (loop--) {
|
||||
let row = startX
|
||||
let col = startY
|
||||
// -->
|
||||
for (; col < n + startY - offset; col++) {
|
||||
arr[i++] = matrix[row][col]
|
||||
}
|
||||
// down
|
||||
for (; row < m + startX - offset; row++) {
|
||||
arr[i++] = matrix[row][col]
|
||||
}
|
||||
// <--
|
||||
for (; col > startY; col--) {
|
||||
arr[i++] = matrix[row][col]
|
||||
}
|
||||
for (; row > startX; row--) {
|
||||
arr[i++] = matrix[row][col]
|
||||
}
|
||||
startX++
|
||||
startY++
|
||||
offset += 2
|
||||
}
|
||||
if (Math.min(m, n) % 2 === 1) {
|
||||
if (n > m) {
|
||||
for (let j = mid; j < mid + n - m + 1; j++) {
|
||||
arr[i++] = matrix[mid][j]
|
||||
}
|
||||
} else {
|
||||
for (let j = mid; j < mid + m - n + 1; j++) {
|
||||
arr[i++] = matrix[j][mid]
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
|
@ -688,7 +688,7 @@ public class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### Ruby#:
|
||||
### Ruby:
|
||||
```ruby
|
||||
def generate_matrix(n)
|
||||
result = Array.new(n) { Array.new(n, 0) }
|
||||
|
@ -50,9 +50,9 @@
|
||||
* 1 <= m, n <= 100
|
||||
* 题目数据保证答案小于等于 2 * 10^9
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[动态规划中如何初始化很重要!| LeetCode:62.不同路径](https://www.bilibili.com/video/BV1ve4y1x7Eu/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划中如何初始化很重要!| LeetCode:62.不同路径](https://www.bilibili.com/video/BV1ve4y1x7Eu/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
## 思路
|
||||
|
||||
|
@ -46,9 +46,9 @@
|
||||
* 1 <= m, n <= 100
|
||||
* obstacleGrid[i][j] 为 0 或 1
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[动态规划,这次遇到障碍了| LeetCode:63. 不同路径 II](https://www.bilibili.com/video/BV1Ld4y1k7c6/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划,这次遇到障碍了| LeetCode:63. 不同路径 II](https://www.bilibili.com/video/BV1Ld4y1k7c6/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
|
@ -403,6 +403,64 @@ int minDistance(char * word1, char * word2){
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn min_distance(word1: String, word2: String) -> i32 {
|
||||
let mut dp = vec![vec![0; word2.len() + 1]; word1.len() + 1];
|
||||
for i in 1..=word2.len() {
|
||||
dp[0][i] = i;
|
||||
}
|
||||
|
||||
for (j, v) in dp.iter_mut().enumerate().skip(1) {
|
||||
v[0] = j;
|
||||
}
|
||||
for (i, char1) in word1.chars().enumerate() {
|
||||
for (j, char2) in word2.chars().enumerate() {
|
||||
if char1 == char2 {
|
||||
dp[i + 1][j + 1] = dp[i][j];
|
||||
continue;
|
||||
}
|
||||
dp[i + 1][j + 1] = dp[i][j + 1].min(dp[i + 1][j]).min(dp[i][j]) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
dp[word1.len()][word2.len()] as i32
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 一维 dp
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn min_distance(word1: String, word2: String) -> i32 {
|
||||
let mut dp = vec![0; word1.len() + 1];
|
||||
for (i, v) in dp.iter_mut().enumerate().skip(1) {
|
||||
*v = i;
|
||||
}
|
||||
|
||||
for char2 in word2.chars() {
|
||||
// 相当于 dp[i][0] 的初始化
|
||||
let mut pre = dp[0];
|
||||
dp[0] += 1; // j = 0, 将前 i 个字符变成空串的个数
|
||||
for (j, char1) in word1.chars().enumerate() {
|
||||
let temp = dp[j + 1];
|
||||
if char1 == char2 {
|
||||
dp[j + 1] = pre;
|
||||
} else {
|
||||
dp[j + 1] = dp[j + 1].min(dp[j]).min(pre) + 1;
|
||||
}
|
||||
pre = temp;
|
||||
}
|
||||
}
|
||||
|
||||
dp[word1.len()] as i32
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -725,62 +725,6 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
Rust
|
||||
|
||||
双指针预处理
|
||||
```rust
|
||||
|
||||
impl Solution {
|
||||
pub fn largest_rectangle_area(v: Vec<i32>) -> i32 {
|
||||
let n = v.len();
|
||||
let mut left_smaller_idx = vec![-1; n];
|
||||
let mut right_smaller_idx = vec![n as i32; n];
|
||||
for i in 1..n {
|
||||
let mut mid = i as i32 - 1;
|
||||
while mid >= 0 && v[mid as usize] >= v[i] {
|
||||
mid = left_smaller_idx[mid as usize];
|
||||
}
|
||||
left_smaller_idx[i] = mid;
|
||||
}
|
||||
for i in (0..n-1).rev() {
|
||||
let mut mid = i + 1;
|
||||
while mid < n && v[mid] >= v[i] {
|
||||
mid = right_smaller_idx[mid] as usize;
|
||||
}
|
||||
right_smaller_idx[i] = mid as i32;
|
||||
}
|
||||
let mut res = 0;
|
||||
for (idx, &e) in v.iter().enumerate() {
|
||||
res = res.max((right_smaller_idx[idx] - left_smaller_idx[idx] - 1) * e);
|
||||
}
|
||||
dbg!(res)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
单调栈
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn largest_rectangle_area1(mut v: Vec<i32>) -> i32 {
|
||||
v.insert(0, 0); // 便于使第一个元素能够有左侧<=它的值
|
||||
v.push(0); // 便于在结束处理最后一个元素后清空残留在栈中的值
|
||||
let mut res = 0;
|
||||
let mut stack = vec![]; // 递增的栈
|
||||
for (idx, &e) in v.iter().enumerate() {
|
||||
while !stack.is_empty() && v[*stack.last().unwrap()] > e {
|
||||
let pos = stack.pop().unwrap();
|
||||
let prev_pos = *stack.last().unwrap();
|
||||
let s = (idx - prev_pos - 1) as i32 * v[pos];
|
||||
res = res.max(s);
|
||||
}
|
||||
stack.push(idx);
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 90.子集II
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/subsets-ii/)
|
||||
|
@ -16,9 +16,9 @@
|
||||
|
||||

|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[动态规划找到子状态之间的关系很重要!| LeetCode:96.不同的二叉搜索树](https://www.bilibili.com/video/BV1eK411o7QA/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划找到子状态之间的关系很重要!| LeetCode:96.不同的二叉搜索树](https://www.bilibili.com/video/BV1eK411o7QA/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
|
@ -314,6 +314,63 @@ function numDistinct(s: string, t: string): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn num_distinct(s: String, t: String) -> i32 {
|
||||
if s.len() < t.len() {
|
||||
return 0;
|
||||
}
|
||||
let mut dp = vec![vec![0; s.len() + 1]; t.len() + 1];
|
||||
// i = 0, t 为空字符串,s 作为子序列的个数为 1(删除 s 所有元素)
|
||||
dp[0] = vec![1; s.len() + 1];
|
||||
for (i, char_t) in t.chars().enumerate() {
|
||||
for (j, char_s) in s.chars().enumerate() {
|
||||
if char_t == char_s {
|
||||
// t 的前 i 个字符在 s 的前 j 个字符中作为子序列的个数
|
||||
dp[i + 1][j + 1] = dp[i][j] + dp[i + 1][j];
|
||||
continue;
|
||||
}
|
||||
dp[i + 1][j + 1] = dp[i + 1][j];
|
||||
}
|
||||
}
|
||||
dp[t.len()][s.len()]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 滚动数组
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn num_distinct(s: String, t: String) -> i32 {
|
||||
if s.len() < t.len() {
|
||||
return 0;
|
||||
}
|
||||
let (s, t) = (s.into_bytes(), t.into_bytes());
|
||||
// 对于 t 为空字符串,s 作为子序列的个数为 1(删除 s 所有元素)
|
||||
let mut dp = vec![1; s.len() + 1];
|
||||
for char_t in t {
|
||||
// dp[i - 1][j - 1],dp[j + 1] 更新之前的值
|
||||
let mut pre = dp[0];
|
||||
// 当开始遍历 t,s 的前 0 个字符无法包含任意子序列
|
||||
dp[0] = 0;
|
||||
for (j, &char_s) in s.iter().enumerate() {
|
||||
let temp = dp[j + 1];
|
||||
if char_t == char_s {
|
||||
dp[j + 1] = pre + dp[j];
|
||||
} else {
|
||||
dp[j + 1] = dp[j];
|
||||
}
|
||||
pre = temp;
|
||||
}
|
||||
}
|
||||
dp[s.len()]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
@ -433,7 +433,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### python:
|
||||
### Python:
|
||||
(版本一)先删除空白,然后整个反转,最后单词反转。
|
||||
**因为字符串是不可变类型,所以反转单词的时候,需要将其转换成列表,然后通过join函数再将其转换成列表,所以空间复杂度不是O(1)**
|
||||
|
||||
@ -547,26 +547,28 @@ func reverseWords(s string) string {
|
||||
b = b[:slowIndex]
|
||||
}
|
||||
//2.反转整个字符串
|
||||
reverse(&b, 0, len(b)-1)
|
||||
reverse(b)
|
||||
//3.反转单个单词 i单词开始位置,j单词结束位置
|
||||
i := 0
|
||||
for i < len(b) {
|
||||
j := i
|
||||
for ; j < len(b) && b[j] != ' '; j++ {
|
||||
}
|
||||
reverse(&b, i, j-1)
|
||||
reverse(b[i:j])
|
||||
i = j
|
||||
i++
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func reverse(b *[]byte, left, right int) {
|
||||
for left < right {
|
||||
(*b)[left], (*b)[right] = (*b)[right], (*b)[left]
|
||||
left++
|
||||
right--
|
||||
}
|
||||
func reverse(b []byte) {
|
||||
left := 0
|
||||
right := len(b) - 1
|
||||
for left < right {
|
||||
b[left], b[right] = b[right], b[left]
|
||||
left++
|
||||
right--
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@ -974,4 +976,3 @@ char * reverseWords(char * s){
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -529,4 +529,3 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -197,7 +197,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
### Python
|
||||
BFS solution
|
||||
```python
|
||||
@ -237,6 +237,7 @@ class Solution:
|
||||
continue
|
||||
q.append((next_i, next_j))
|
||||
visited[next_i][next_j] = True
|
||||
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
@ -244,3 +245,4 @@ class Solution:
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
```
|
||||
|
||||
|
@ -218,6 +218,67 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
# 版本一
|
||||
class Solution:
|
||||
def numIslands(self, grid: List[List[str]]) -> int:
|
||||
m, n = len(grid), len(grid[0])
|
||||
visited = [[False] * n for _ in range(m)]
|
||||
dirs = [(-1, 0), (0, 1), (1, 0), (0, -1)] # 四个方向
|
||||
result = 0
|
||||
|
||||
def dfs(x, y):
|
||||
for d in dirs:
|
||||
nextx = x + d[0]
|
||||
nexty = y + d[1]
|
||||
if nextx < 0 or nextx >= m or nexty < 0 or nexty >= n: # 越界了,直接跳过
|
||||
continue
|
||||
if not visited[nextx][nexty] and grid[nextx][nexty] == '1': # 没有访问过的同时是陆地的
|
||||
visited[nextx][nexty] = True
|
||||
dfs(nextx, nexty)
|
||||
|
||||
for i in range(m):
|
||||
for j in range(n):
|
||||
if not visited[i][j] and grid[i][j] == '1':
|
||||
visited[i][j] = True
|
||||
result += 1 # 遇到没访问过的陆地,+1
|
||||
dfs(i, j) # 将与其链接的陆地都标记上 true
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
```python
|
||||
# 版本二
|
||||
class Solution:
|
||||
def numIslands(self, grid: List[List[str]]) -> int:
|
||||
m, n = len(grid), len(grid[0])
|
||||
visited = [[False] * n for _ in range(m)]
|
||||
dirs = [(-1, 0), (0, 1), (1, 0), (0, -1)] # 四个方向
|
||||
result = 0
|
||||
|
||||
def dfs(x, y):
|
||||
if visited[x][y] or grid[x][y] == '0':
|
||||
return # 终止条件:访问过的节点 或者 遇到海水
|
||||
visited[x][y] = True
|
||||
for d in dirs:
|
||||
nextx = x + d[0]
|
||||
nexty = y + d[1]
|
||||
if nextx < 0 or nextx >= m or nexty < 0 or nexty >= n: # 越界了,直接跳过
|
||||
continue
|
||||
dfs(nextx, nexty)
|
||||
|
||||
for i in range(m):
|
||||
for j in range(n):
|
||||
if not visited[i][j] and grid[i][j] == '1':
|
||||
result += 1 # 遇到没访问过的陆地,+1
|
||||
dfs(i, j) # 将与其链接的陆地都标记上 true
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -423,29 +423,61 @@ impl Solution {
|
||||
### C:
|
||||
|
||||
```C
|
||||
typedef struct HashNodeTag {
|
||||
int key; /* num */
|
||||
struct HashNodeTag *next;
|
||||
}HashNode;
|
||||
|
||||
/* Calcualte the hash key */
|
||||
static inline int hash(int key, int size) {
|
||||
int index = key % size;
|
||||
return (index > 0) ? (index) : (-index);
|
||||
}
|
||||
|
||||
/* Calculate the sum of the squares of its digits*/
|
||||
static inline int calcSquareSum(int num) {
|
||||
unsigned int sum = 0;
|
||||
while(num > 0) {
|
||||
sum += (num % 10) * (num % 10);
|
||||
num = num/10;
|
||||
int get_sum(int n) {
|
||||
int sum = 0;
|
||||
div_t n_div = { .quot = n };
|
||||
while (n_div.quot != 0) {
|
||||
n_div = div(n_div.quot, 10);
|
||||
sum += n_div.rem * n_div.rem;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
// (版本1)使用数组
|
||||
bool isHappy(int n) {
|
||||
// sum = a1^2 + a2^2 + ... ak^2
|
||||
// first round:
|
||||
// 1 <= k <= 10
|
||||
// 1 <= sum <= 1 + 81 * 9 = 730
|
||||
// second round:
|
||||
// 1 <= k <= 3
|
||||
// 1 <= sum <= 36 + 81 * 2 = 198
|
||||
// third round:
|
||||
// 1 <= sum <= 81 * 2 = 162
|
||||
// fourth round:
|
||||
// 1 <= sum <= 81 * 2 = 162
|
||||
|
||||
Scala:
|
||||
uint8_t visited[163] = { 0 };
|
||||
int sum = get_sum(get_sum(n));
|
||||
int next_n = sum;
|
||||
|
||||
while (next_n != 1) {
|
||||
sum = get_sum(next_n);
|
||||
|
||||
if (visited[sum]) return false;
|
||||
|
||||
visited[sum] = 1;
|
||||
next_n = sum;
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// (版本2)使用快慢指针
|
||||
bool isHappy(int n) {
|
||||
int slow = n;
|
||||
int fast = n;
|
||||
|
||||
do {
|
||||
slow = get_sum(slow);
|
||||
fast = get_sum(get_sum(fast));
|
||||
} while (slow != fast);
|
||||
|
||||
return (fast == 1);
|
||||
}
|
||||
```
|
||||
|
||||
### Scala:
|
||||
```scala
|
||||
object Solution {
|
||||
// 引入mutable
|
||||
|
@ -3,6 +3,7 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 283. 移动零:动态规划:一样的套路,再求一次完全平方数
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/move-zeroes/)
|
||||
|
@ -130,18 +130,16 @@ public:
|
||||
class Solution {
|
||||
public int lengthOfLIS(int[] nums) {
|
||||
int[] dp = new int[nums.length];
|
||||
int res = 0;
|
||||
Arrays.fill(dp, 1);
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
for (int i = 1; i < dp.length; i++) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (nums[i] > nums[j]) {
|
||||
dp[i] = Math.max(dp[i], dp[j] + 1);
|
||||
}
|
||||
res = Math.max(res, dp[i]);
|
||||
}
|
||||
}
|
||||
int res = 0;
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
res = Math.max(res, dp[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -294,7 +292,7 @@ function lengthOfLIS(nums: number[]): number {
|
||||
|
||||
```rust
|
||||
pub fn length_of_lis(nums: Vec<i32>) -> i32 {
|
||||
let mut dp = vec![1; nums.len() + 1];
|
||||
let mut dp = vec![1; nums.len()];
|
||||
let mut result = 1;
|
||||
for i in 1..nums.len() {
|
||||
for j in 0..i {
|
||||
@ -309,7 +307,6 @@ pub fn length_of_lis(nums: Vec<i32>) -> i32 {
|
||||
```
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
## 算法公开课
|
||||
|
||||
**如果对回溯算法基础还不了解的话,我还特意录制了一期视频,[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/) ,相信结合视频再看本篇题解,更有助于大家对本题的理解。**
|
||||
|
||||
## 思路
|
||||
|
||||
@ -790,4 +790,3 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -22,9 +22,9 @@
|
||||
* 说明: 你可以假设 n 不小于 2 且不大于 58。
|
||||
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**《代码随想录》算法视频公开课:[动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分](https://www.bilibili.com/video/BV1Mg411q7YJ/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划,本题关键在于理解递推公式!| LeetCode:343. 整数拆分](https://www.bilibili.com/video/BV1Mg411q7YJ/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
|
||||
## 思路
|
||||
@ -473,3 +473,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -465,6 +465,25 @@ object Solution {
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
###Ruby
|
||||
```ruby
|
||||
def intersection(nums1, nums2)
|
||||
hash = {}
|
||||
result = {}
|
||||
|
||||
nums1.each do |num|
|
||||
hash[num] = 1 if hash[num].nil?
|
||||
end
|
||||
|
||||
nums2.each do |num|
|
||||
#取nums1和nums2交集
|
||||
result[num] = 1 if hash[num] != nil
|
||||
end
|
||||
|
||||
return result.keys
|
||||
end
|
||||
```
|
||||
## 相关题目
|
||||
|
||||
* [350.两个数组的交集 II](https://leetcode.cn/problems/intersection-of-two-arrays-ii/)
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
|
||||
### 哈希解法
|
||||
|
||||
因为题目所只有小写字母,那可以采用空间换取时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数。
|
||||
因为题目说只有小写字母,那可以采用空间换取时间的哈希策略,用一个长度为26的数组来记录magazine里字母出现的次数。
|
||||
|
||||
然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。
|
||||
|
||||
|
@ -259,9 +259,49 @@ func isSubsequence(s string, t string) bool {
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn is_subsequence(s: String, t: String) -> bool {
|
||||
let mut dp = vec![vec![0; t.len() + 1]; s.len() + 1];
|
||||
for (i, char_s) in s.chars().enumerate() {
|
||||
for (j, char_t) in t.chars().enumerate() {
|
||||
if char_s == char_t {
|
||||
dp[i + 1][j + 1] = dp[i][j] + 1;
|
||||
continue;
|
||||
}
|
||||
dp[i + 1][j + 1] = dp[i + 1][j]
|
||||
}
|
||||
}
|
||||
dp[s.len()][t.len()] == s.len()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 滚动数组
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn is_subsequence(s: String, t: String) -> bool {
|
||||
let mut dp = vec![0; t.len() + 1];
|
||||
let (s, t) = (s.as_bytes(), t.as_bytes());
|
||||
for &byte_s in s {
|
||||
let mut pre = 0;
|
||||
for j in 0..t.len() {
|
||||
let temp = dp[j + 1];
|
||||
if byte_s == t[j] {
|
||||
dp[j + 1] = pre + 1;
|
||||
} else {
|
||||
dp[j + 1] = dp[j];
|
||||
}
|
||||
pre = temp;
|
||||
}
|
||||
}
|
||||
dp[t.len()] == s.len()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
@ -4,7 +4,7 @@
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 416. 分割等和子集
|
||||
# 416. 分割等和子集
|
||||
|
||||
[力扣题目链接](https://leetcode.cn/problems/partition-equal-subset-sum/)
|
||||
|
||||
@ -730,4 +730,3 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -302,6 +302,104 @@ var islandPerimeter = function(grid) {
|
||||
};
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 方法一:深度优先搜索(DFS)
|
||||
* @param grid 二维网格地图,其中 grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域
|
||||
* @returns 岛屿的周长
|
||||
*/
|
||||
function islandPerimeter(grid: number[][]): number {
|
||||
// 处理特殊情况:网格为空或行列数为 0,直接返回 0
|
||||
if (!grid || grid.length === 0 || grid[0].length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取网格的行数和列数
|
||||
const rows = grid.length;
|
||||
const cols = grid[0].length;
|
||||
let perimeter = 0; // 岛屿的周长
|
||||
|
||||
/**
|
||||
* 深度优先搜索函数
|
||||
* @param i 当前格子的行索引
|
||||
* @param j 当前格子的列索引
|
||||
*/
|
||||
const dfs = (i: number, j: number) => {
|
||||
// 如果当前位置超出网格范围,或者当前位置是水域(grid[i][j] === 0),则周长增加1
|
||||
if (i < 0 || i >= rows || j < 0 || j >= cols || grid[i][j] === 0) {
|
||||
perimeter++;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果当前位置已经访问过(grid[i][j] === -1),则直接返回
|
||||
if (grid[i][j] === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 标记当前位置为已访问(-1),避免重复计算
|
||||
grid[i][j] = -1;
|
||||
|
||||
// 继续搜索上、下、左、右四个方向
|
||||
dfs(i + 1, j);
|
||||
dfs(i - 1, j);
|
||||
dfs(i, j + 1);
|
||||
dfs(i, j - 1);
|
||||
};
|
||||
|
||||
// 遍历整个网格,找到第一个陆地格子(grid[i][j] === 1),并以此为起点进行深度优先搜索
|
||||
for (let i = 0; i < rows; i++) {
|
||||
for (let j = 0; j < cols; j++) {
|
||||
if (grid[i][j] === 1) {
|
||||
dfs(i, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return perimeter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法二:遍历每个陆地格子,统计周长
|
||||
* @param grid 二维网格地图,其中 grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域
|
||||
* @returns 岛屿的周长
|
||||
*/
|
||||
function islandPerimeter(grid: number[][]): number {
|
||||
// 处理特殊情况:网格为空或行列数为 0,直接返回 0
|
||||
if (!grid || grid.length === 0 || grid[0].length === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取网格的行数和列数
|
||||
const rows = grid.length;
|
||||
const cols = grid[0].length;
|
||||
let perimeter = 0; // 岛屿的周长
|
||||
|
||||
// 遍历整个网格
|
||||
for (let i = 0; i < rows; i++) {
|
||||
for (let j = 0; j < cols; j++) {
|
||||
// 如果当前格子是陆地(grid[i][j] === 1)
|
||||
if (grid[i][j] === 1) {
|
||||
perimeter += 4; // 周长先加上4个边
|
||||
|
||||
// 判断当前格子的上方是否也是陆地,如果是,则周长减去2个边
|
||||
if (i > 0 && grid[i - 1][j] === 1) {
|
||||
perimeter -= 2;
|
||||
}
|
||||
|
||||
// 判断当前格子的左方是否也是陆地,如果是,则周长减去2个边
|
||||
if (j > 0 && grid[i][j - 1] === 1) {
|
||||
perimeter -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return perimeter;
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
@ -294,4 +294,3 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -272,7 +272,26 @@ function longestPalindromeSubseq(s: string): number {
|
||||
};
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn longest_palindrome_subseq(s: String) -> i32 {
|
||||
let mut dp = vec![vec![0; s.len()]; s.len()];
|
||||
for i in (0..s.len()).rev() {
|
||||
dp[i][i] = 1;
|
||||
for j in i + 1..s.len() {
|
||||
if s[i..=i] == s[j..=j] {
|
||||
dp[i][j] = dp[i + 1][j - 1] + 2;
|
||||
continue;
|
||||
}
|
||||
dp[i][j] = dp[i + 1][j].max(dp[i][j - 1]);
|
||||
}
|
||||
}
|
||||
dp[0][s.len() - 1]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<p align="center">
|
||||
|
@ -370,7 +370,51 @@ function minDistance(word1: string, word2: string): number {
|
||||
};
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn min_distance(word1: String, word2: String) -> i32 {
|
||||
let mut dp = vec![vec![0; word2.len() + 1]; word1.len() + 1];
|
||||
for i in 0..word1.len() {
|
||||
dp[i + 1][0] = i + 1;
|
||||
}
|
||||
for j in 0..word2.len() {
|
||||
dp[0][j + 1] = j + 1;
|
||||
}
|
||||
for (i, char1) in word1.chars().enumerate() {
|
||||
for (j, char2) in word2.chars().enumerate() {
|
||||
if char1 == char2 {
|
||||
dp[i + 1][j + 1] = dp[i][j];
|
||||
continue;
|
||||
}
|
||||
dp[i + 1][j + 1] = dp[i][j + 1].min(dp[i + 1][j]) + 1;
|
||||
}
|
||||
}
|
||||
dp[word1.len()][word2.len()] as i32
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 版本 2
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn min_distance(word1: String, word2: String) -> i32 {
|
||||
let mut dp = vec![vec![0; word2.len() + 1]; word1.len() + 1];
|
||||
for (i, char1) in word1.chars().enumerate() {
|
||||
for (j, char2) in word2.chars().enumerate() {
|
||||
if char1 == char2 {
|
||||
dp[i + 1][j + 1] = dp[i][j] + 1;
|
||||
continue;
|
||||
}
|
||||
dp[i + 1][j + 1] = dp[i][j + 1].max(dp[i + 1][j]);
|
||||
}
|
||||
}
|
||||
(word1.len() + word2.len() - 2 * dp[word1.len()][word2.len()]) as i32
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<p align="center">
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
注意: 合并必须从两个树的根节点开始。
|
||||
|
||||
# 算法公开课
|
||||
## 算法公开课
|
||||
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树](https://www.bilibili.com/video/BV1m14y1Y7JK),相信结合视频在看本篇题解,更有助于大家对本题的理解**。
|
||||
|
||||
@ -793,3 +793,4 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -521,8 +521,51 @@ function expandRange(s: string, left: number, right: number): number {
|
||||
}
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn count_substrings(s: String) -> i32 {
|
||||
let mut dp = vec![vec![false; s.len()]; s.len()];
|
||||
let mut res = 0;
|
||||
|
||||
for i in (0..s.len()).rev() {
|
||||
for j in i..s.len() {
|
||||
if s[i..=i] == s[j..=j] && (j - i <= 1 || dp[i + 1][j - 1]) {
|
||||
dp[i][j] = true;
|
||||
res += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 双指针
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn count_substrings(s: String) -> i32 {
|
||||
let mut res = 0;
|
||||
for i in 0..s.len() {
|
||||
res += Self::extend(&s, i, i, s.len());
|
||||
res += Self::extend(&s, i, i + 1, s.len());
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
fn extend(s: &str, mut i: usize, mut j: usize, len: usize) -> i32 {
|
||||
let mut res = 0;
|
||||
while i < len && j < len && s[i..=i] == s[j..=j] {
|
||||
res += 1;
|
||||
i = i.wrapping_sub(1);
|
||||
j += 1;
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
|
@ -302,8 +302,9 @@ func findLengthOfLCIS(nums []int) int {
|
||||
}
|
||||
```
|
||||
|
||||
### Rust:
|
||||
|
||||
### Rust:
|
||||
>动态规划
|
||||
```rust
|
||||
pub fn find_length_of_lcis(nums: Vec<i32>) -> i32 {
|
||||
if nums.is_empty() {
|
||||
@ -321,6 +322,27 @@ pub fn find_length_of_lcis(nums: Vec<i32>) -> i32 {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
> 贪心
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn find_length_of_lcis(nums: Vec<i32>) -> i32 {
|
||||
let (mut res, mut count) = (1, 1);
|
||||
for i in 1..nums.len() {
|
||||
if nums[i] > nums[i - 1] {
|
||||
count += 1;
|
||||
res = res.max(count);
|
||||
continue;
|
||||
}
|
||||
count = 1;
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Javascript:
|
||||
|
||||
> 动态规划:
|
||||
|
@ -22,7 +22,7 @@
|
||||
* 输出:6
|
||||
* 解释:答案不应该是 11 ,因为岛屿只能包含水平或垂直这四个方向上的 1 。
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
|
||||
注意题目中每座岛屿只能由**水平方向和/或竖直方向上**相邻的陆地连接形成。
|
||||
@ -38,7 +38,7 @@
|
||||
* [DFS理论基础](https://programmercarl.com/图论深搜理论基础.html)
|
||||
* [BFS理论基础](https://programmercarl.com/图论广搜理论基础.html)
|
||||
|
||||
## DFS
|
||||
### DFS
|
||||
|
||||
很多同学,写dfs其实也是凭感觉来,有的时候dfs函数中写终止条件才能过,有的时候 dfs函数不写终止添加也能过!
|
||||
|
||||
@ -134,7 +134,7 @@ public:
|
||||
以上两种写法的区别,我在题解: [DFS,BDF 你没注意的细节都给你列出来了!LeetCode:200. 岛屿数量](https://leetcode.cn/problems/number-of-islands/solution/by-carlsun-2-n72a/)做了详细介绍。
|
||||
|
||||
|
||||
## BFS
|
||||
### BFS
|
||||
|
||||
关于广度优先搜索,如果大家还不了解的话,看这里:[广度优先搜索精讲](https://programmercarl.com/图论广搜理论基础.html)
|
||||
|
||||
@ -188,9 +188,9 @@ public:
|
||||
|
||||
```
|
||||
|
||||
# 其它语言版本
|
||||
## Java
|
||||
### DFS
|
||||
## 其它语言版本
|
||||
### Java
|
||||
#### DFS
|
||||
```java
|
||||
// DFS
|
||||
class Solution {
|
||||
@ -236,7 +236,7 @@ class Solution {
|
||||
|
||||
|
||||
```
|
||||
### BFS
|
||||
#### BFS
|
||||
```java
|
||||
//BFS
|
||||
class Solution {
|
||||
@ -290,7 +290,7 @@ class Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
### DFS 優化(遇到島嶼後,就把他淹沒)
|
||||
#### DFS 優化(遇到島嶼後,就把他淹沒)
|
||||
```java
|
||||
//这里使用深度优先搜索 DFS 来完成本道题目。我们使用 DFS 计算一个岛屿的面积,同时维护计算过的最大的岛屿面积。同时,为了避免对岛屿重复计算,我们在 DFS 的时候对岛屿进行 “淹没” 操作,即将岛屿所占的地方置为 0。
|
||||
public int maxAreaOfIsland(int[][] grid) {
|
||||
@ -319,8 +319,8 @@ public int dfs(int[][] grid,int i,int j){
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
### BFS
|
||||
### Python
|
||||
#### BFS
|
||||
```python
|
||||
class Solution:
|
||||
def __init__(self):
|
||||
@ -359,7 +359,7 @@ class Solution:
|
||||
self.count += 1
|
||||
queue.append((new_x, new_y))
|
||||
```
|
||||
### DFS
|
||||
#### DFS
|
||||
```python
|
||||
class Solution:
|
||||
def __init__(self):
|
||||
@ -394,3 +394,4 @@ class Solution:
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -150,8 +150,8 @@ public:
|
||||
|
||||
* [35.搜索插入位置](https://programmercarl.com/0035.搜索插入位置.html)
|
||||
* [34.在排序数组中查找元素的第一个和最后一个位置](https://programmercarl.com/0034.%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE.html)
|
||||
* 69.x 的平方根
|
||||
* 367.有效的完全平方数
|
||||
* [69.x 的平方根](https://leetcode.cn/problems/sqrtx/)
|
||||
* [367.有效的完全平方数](https://leetcode.cn/problems/valid-perfect-square/)
|
||||
|
||||
|
||||
|
||||
@ -760,9 +760,58 @@ object Solution {
|
||||
}
|
||||
}
|
||||
```
|
||||
**Dart:**
|
||||
|
||||
|
||||
|
||||
```dart
|
||||
(版本一)左闭右闭区间
|
||||
class Solution {
|
||||
int search(List<int> nums, int target) {
|
||||
int left = 0;
|
||||
int right = nums.length - 1;
|
||||
while (left <= right) {
|
||||
int middle = ((left + right)/2).truncate();
|
||||
switch (nums[middle].compareTo(target)) {
|
||||
case 1:
|
||||
right = middle - 1;
|
||||
continue;
|
||||
case -1:
|
||||
left = middle + 1;
|
||||
continue;
|
||||
default:
|
||||
return middle;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
(版本二)左闭右开区间
|
||||
class Solution {
|
||||
int search(List<int> nums, int target) {
|
||||
int left = 0;
|
||||
int right = nums.length;
|
||||
while (left < right) {
|
||||
int middle = left + ((right - left) >> 1);
|
||||
switch (nums[middle].compareTo(target)) {
|
||||
case 1:
|
||||
right = middle;
|
||||
continue;
|
||||
case -1:
|
||||
left = middle + 1;
|
||||
continue;
|
||||
default:
|
||||
return middle;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
本题相对于[贪心算法:122.买卖股票的最佳时机II](https://programmercarl.com/0122.买卖股票的最佳时机II.html),多添加了一个条件就是手续费。
|
||||
|
||||
## 贪心算法
|
||||
### 贪心算法
|
||||
|
||||
在[贪心算法:122.买卖股票的最佳时机II](https://programmercarl.com/0122.买卖股票的最佳时机II.html)中使用贪心策略不用关心具体什么时候买卖,只要收集每天的正利润,最后稳稳的就是最大利润了。
|
||||
|
||||
@ -93,7 +93,7 @@ public:
|
||||
|
||||
大家也可以发现,情况三,那块代码是可以删掉的,我是为了让代码表达清晰,所以没有精简。
|
||||
|
||||
## 动态规划
|
||||
### 动态规划
|
||||
|
||||
我在公众号「代码随想录」里将在下一个系列详细讲解动态规划,所以本题解先给出我的C++代码(带详细注释),感兴趣的同学可以自己先学习一下。
|
||||
|
||||
@ -364,3 +364,4 @@ object Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -536,6 +536,29 @@ function findLength(nums1: number[], nums2: number[]): number {
|
||||
};
|
||||
```
|
||||
|
||||
Rust:
|
||||
|
||||
> 滚动数组
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn find_length(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
|
||||
let (mut res, mut dp) = (0, vec![0; nums2.len()]);
|
||||
|
||||
for n1 in nums1 {
|
||||
for j in (0..nums2.len()).rev() {
|
||||
if n1 == nums2[j] {
|
||||
dp[j] = if j == 0 { 1 } else { dp[j - 1] + 1 };
|
||||
res = res.max(dp[j]);
|
||||
} else {
|
||||
dp[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -149,7 +149,7 @@ public:
|
||||
|
||||
```
|
||||
|
||||
# 总结
|
||||
## 总结
|
||||
|
||||
本题是比较基础的深度优先搜索模板题,这种有向图路径问题,最合适使用深搜,当然本题也可以使用广搜,但广搜相对来说就麻烦了一些,需要记录一下路径。
|
||||
|
||||
@ -159,7 +159,7 @@ public:
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
Java
|
||||
### Java
|
||||
|
||||
```Java
|
||||
// 深度优先遍历
|
||||
@ -190,7 +190,8 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
Python
|
||||
### Python
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def __init__(self):
|
||||
@ -216,9 +217,9 @@ class Solution:
|
||||
self.path.pop() # 回溯
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
* 输出: 4
|
||||
* 解释: 没有0可以让我们变成1,面积依然为 4。
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
本题的一个暴力想法,应该是遍历地图尝试 将每一个 0 改成1,然后去搜索地图中的最大的岛屿面积。
|
||||
|
||||
@ -219,9 +219,9 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
# 其他语言版本
|
||||
## 其他语言版本
|
||||
|
||||
## Java
|
||||
### Java
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
@ -286,4 +286,3 @@ class Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
本文将给出 空间复杂度O(n)的栈模拟方法 以及空间复杂度是O(1)的双指针方法。
|
||||
|
||||
## 普通方法(使用栈的思路)
|
||||
### 普通方法(使用栈的思路)
|
||||
|
||||
这道题目一看就是要使用栈的节奏,这种匹配(消除)问题也是栈的擅长所在,跟着一起刷题的同学应该知道,在[栈与队列:匹配问题都是栈的强项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html),我就已经提过了一次使用栈来做类似的事情了。
|
||||
|
||||
@ -100,7 +100,7 @@ public:
|
||||
* 时间复杂度:O(n + m)
|
||||
* 空间复杂度:O(n + m)
|
||||
|
||||
## 优化方法(从后向前双指针)
|
||||
### 优化方法(从后向前双指针)
|
||||
|
||||
当然还可以有使用 O(1) 的空间复杂度来解决该问题。
|
||||
|
||||
@ -289,7 +289,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### python
|
||||
### Python
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
@ -591,3 +591,4 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -525,6 +525,54 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
Ruby:
|
||||
```ruby
|
||||
def common_chars(words)
|
||||
result = []
|
||||
#统计所有字符串里字符出现的最小频率
|
||||
hash = {}
|
||||
#初始化标识
|
||||
is_first = true
|
||||
|
||||
words.each do |word|
|
||||
#记录共同字符
|
||||
chars = []
|
||||
word.split('').each do |chr|
|
||||
#第一个字符串初始化
|
||||
if is_first
|
||||
chars << chr
|
||||
else
|
||||
#字母之前出现过的最小次数
|
||||
if hash[chr] != nil && hash[chr] > 0
|
||||
hash[chr] -= 1
|
||||
chars << chr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_first = false
|
||||
#清除hash,更新字符最小频率
|
||||
hash.clear
|
||||
chars.each do |chr|
|
||||
if hash[chr] != nil
|
||||
hash[chr] += 1
|
||||
else
|
||||
hash[chr] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#字符最小频率hash转换为字符数组
|
||||
hash.keys.each do |key|
|
||||
for i in 0..hash[key] - 1
|
||||
result << key
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -155,21 +155,44 @@ func max(a, b int) int {
|
||||
### Rust:
|
||||
|
||||
```rust
|
||||
pub fn max_uncrossed_lines(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
|
||||
let (n, m) = (nums1.len(), nums2.len());
|
||||
let mut last = vec![0; m + 1]; // 记录滚动数组
|
||||
let mut dp = vec![0; m + 1];
|
||||
for i in 1..=n {
|
||||
dp.swap_with_slice(&mut last);
|
||||
for j in 1..=m {
|
||||
if nums1[i - 1] == nums2[j - 1] {
|
||||
dp[j] = last[j - 1] + 1;
|
||||
} else {
|
||||
dp[j] = last[j].max(dp[j - 1]);
|
||||
impl Solution {
|
||||
pub fn max_uncrossed_lines(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
|
||||
let mut dp = vec![vec![0; nums2.len() + 1]; nums1.len() + 1];
|
||||
for (i, num1) in nums1.iter().enumerate() {
|
||||
for (j, num2) in nums2.iter().enumerate() {
|
||||
if num1 == num2 {
|
||||
dp[i + 1][j + 1] = dp[i][j] + 1;
|
||||
} else {
|
||||
dp[i + 1][j + 1] = dp[i][j + 1].max(dp[i + 1][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
dp[nums1.len()][nums2.len()]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 滚动数组
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn max_uncrossed_lines(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
|
||||
let mut dp = vec![0; nums2.len() + 1];
|
||||
for num1 in nums1 {
|
||||
let mut prev = 0;
|
||||
for (j, &num2) in nums2.iter().enumerate() {
|
||||
let temp = dp[j + 1];
|
||||
if num1 == num2 {
|
||||
// 使用上一次的状态,防止重复计算
|
||||
dp[j + 1] = prev + 1;
|
||||
} else {
|
||||
dp[j + 1] = dp[j + 1].max(dp[j]);
|
||||
}
|
||||
prev = temp;
|
||||
}
|
||||
}
|
||||
dp[nums2.len()]
|
||||
}
|
||||
dp[m]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -329,25 +329,50 @@ function longestCommonSubsequence(text1: string, text2: string): number {
|
||||
};
|
||||
```
|
||||
|
||||
### Rust:
|
||||
### Rust
|
||||
|
||||
```rust
|
||||
pub fn longest_common_subsequence(text1: String, text2: String) -> i32 {
|
||||
let (n, m) = (text1.len(), text2.len());
|
||||
let (s1, s2) = (text1.as_bytes(), text2.as_bytes());
|
||||
let mut dp = vec![0; m + 1];
|
||||
let mut last = vec![0; m + 1];
|
||||
for i in 1..=n {
|
||||
dp.swap_with_slice(&mut last);
|
||||
for j in 1..=m {
|
||||
dp[j] = if s1[i - 1] == s2[j - 1] {
|
||||
last[j - 1] + 1
|
||||
} else {
|
||||
last[j].max(dp[j - 1])
|
||||
};
|
||||
impl Solution {
|
||||
pub fn longest_common_subsequence(text1: String, text2: String) -> i32 {
|
||||
let mut dp = vec![vec![0; text2.len() + 1]; text1.len() + 1];
|
||||
for (i, c1) in text1.chars().enumerate() {
|
||||
for (j, c2) in text2.chars().enumerate() {
|
||||
if c1 == c2 {
|
||||
dp[i + 1][j + 1] = dp[i][j] + 1;
|
||||
} else {
|
||||
dp[i + 1][j + 1] = dp[i][j + 1].max(dp[i + 1][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
dp[text1.len()][text2.len()]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
一维:
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn longest_common_subsequence(text1: String, text2: String) -> i32 {
|
||||
let mut dp = vec![0; text2.len() + 1];
|
||||
for c1 in text1.chars() {
|
||||
// 初始化 prev
|
||||
let mut prev = 0;
|
||||
|
||||
for (j, c2) in text2.chars().enumerate() {
|
||||
let temp = dp[j + 1];
|
||||
if c1 == c2 {
|
||||
// 使用上一次的状态,防止重复计算
|
||||
dp[j + 1] = prev + 1;
|
||||
} else {
|
||||
dp[j + 1] = dp[j + 1].max(dp[j]);
|
||||
}
|
||||
// 使用上一次的状态更新 prev
|
||||
prev = temp;
|
||||
}
|
||||
}
|
||||
dp[text2.len()]
|
||||
}
|
||||
dp[m]
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -200,10 +200,30 @@ function uniqueOccurrences(arr: number[]): boolean {
|
||||
})
|
||||
return countMap.size === new Set(countMap.values()).size;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
### Go:
|
||||
```Go
|
||||
func uniqueOccurrences(arr []int) bool {
|
||||
count := make(map[int]int) // 统计数字出现的频率
|
||||
for _, v := range arr {
|
||||
count[v] += 1
|
||||
}
|
||||
fre := make(map[int]struct{}) // 看相同频率是否重复出现
|
||||
for _, v := range count {
|
||||
if _, ok := fre[v]; ok {
|
||||
return false
|
||||
}
|
||||
fre[v] = struct{}{}
|
||||
}
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 1791.找出星型图的中心节点
|
||||
|
||||
[题目链接](https://leetcode.cn/problems/find-center-of-star-graph/)
|
||||
@ -55,7 +56,7 @@ public:
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
```
|
||||
```
|
||||
|
||||
以上代码中没有使用 unordered_map,因为遍历的时候,开辟新空间会浪费时间,而采用 vector,这是 空间换时间的一种策略。
|
||||
|
||||
|
@ -138,3 +138,4 @@ public:
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -200,4 +200,3 @@ class Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -142,7 +142,7 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### python:
|
||||
### Python:
|
||||
(版本一)使用切片
|
||||
|
||||
```python
|
||||
@ -338,7 +338,7 @@ func reverseString(_ s: inout [Character], startIndex: Int, endIndex: Int) {
|
||||
```
|
||||
|
||||
|
||||
### PHP
|
||||
### PHP:
|
||||
|
||||
```php
|
||||
function reverseLeftWords($s, $n) {
|
||||
@ -418,4 +418,3 @@ impl Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
|
||||
好啦,我们再一起回顾一下,动态规划专题中我们都讲了哪些内容。
|
||||
|
||||
## 动划基础
|
||||
## 动态规划基础
|
||||
|
||||
* [关于动态规划,你该了解这些!](https://programmercarl.com/动态规划理论基础.html)
|
||||
* [动态规划:斐波那契数](https://programmercarl.com/0509.斐波那契数.html)
|
||||
@ -136,4 +136,3 @@
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
--------------------------
|
||||
|
||||
# 本周小结!(回溯算法系列一)
|
||||
|
||||
## 周一
|
||||
|
||||
本周我们正式开始了回溯算法系列,那么首先当然是概述。
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:[回溯算法:电话号码的字母组合](https://programmercarl.com/0017.电话号码的字母组合.html)
|
||||
|
||||
**注意以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路,后面我再讲解排列的时候就重点介绍**。
|
||||
**注意以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路,后面我在讲解排列的时候会重点介绍**。
|
||||
|
||||
最后还给出了本题的剪枝优化,如下:
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
**一般来说哈希表都是用来快速判断一个元素是否出现集合里**。
|
||||
|
||||
对于哈希表,要知道**哈希函数**和**哈希碰撞**在哈希表中的作用.
|
||||
对于哈希表,要知道**哈希函数**和**哈希碰撞**在哈希表中的作用。
|
||||
|
||||
哈希函数是把传入的key映射到符号表的索引上。
|
||||
|
||||
@ -88,7 +88,7 @@ std::set和std::multiset底层实现都是红黑树,std::unordered_set的底
|
||||
|
||||
map是一种`<key, value>`的结构,本题可以用key保存数值,用value在保存数值所在的下标。所以使用map最为合适。
|
||||
|
||||
C++提供如下三种map::(详情请看[关于哈希表,你该了解这些!](https://programmercarl.com/哈希表理论基础.html))
|
||||
C++提供如下三种map:(详情请看[关于哈希表,你该了解这些!](https://programmercarl.com/哈希表理论基础.html))
|
||||
|
||||
* std::map
|
||||
* std::multimap
|
||||
|
@ -3,6 +3,7 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 栈与队列总结篇
|
||||
|
||||
## 栈与队列的理论基础
|
||||
|
@ -196,7 +196,7 @@ impl Solution{
|
||||
}
|
||||
```
|
||||
|
||||
### Go:
|
||||
### Go
|
||||
|
||||
Go中slice的`append`操作和C++中vector的扩容机制基本相同。
|
||||
|
||||
@ -213,4 +213,3 @@ Go中slice的`append`操作和C++中vector的扩容机制基本相同。
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -3,8 +3,11 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 算法模板
|
||||
|
||||
## 二分查找法
|
||||
## 算法模板
|
||||
|
||||
### 二分查找法
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
@ -29,7 +32,7 @@ public:
|
||||
|
||||
```
|
||||
|
||||
## KMP
|
||||
### KMP
|
||||
|
||||
```CPP
|
||||
void kmp(int* next, const string& s){
|
||||
@ -47,7 +50,7 @@ void kmp(int* next, const string& s){
|
||||
}
|
||||
```
|
||||
|
||||
## 二叉树
|
||||
### 二叉树
|
||||
|
||||
二叉树的定义:
|
||||
|
||||
@ -60,7 +63,7 @@ struct TreeNode {
|
||||
};
|
||||
```
|
||||
|
||||
### 深度优先遍历(递归)
|
||||
#### 深度优先遍历(递归)
|
||||
|
||||
前序遍历(中左右)
|
||||
```CPP
|
||||
@ -90,7 +93,7 @@ void traversal(TreeNode* cur, vector<int>& vec) {
|
||||
}
|
||||
```
|
||||
|
||||
### 深度优先遍历(迭代法)
|
||||
#### 深度优先遍历(迭代法)
|
||||
|
||||
相关题解:[0094.二叉树的中序遍历](https://github.com/youngyangyang04/leetcode/blob/master/problems/0094.二叉树的中序遍历.md)
|
||||
|
||||
@ -170,7 +173,7 @@ vector<int> postorderTraversal(TreeNode* root) {
|
||||
return result;
|
||||
}
|
||||
```
|
||||
### 广度优先遍历(队列)
|
||||
#### 广度优先遍历(队列)
|
||||
|
||||
相关题解:[0102.二叉树的层序遍历](https://programmercarl.com/0102.二叉树的层序遍历.html)
|
||||
|
||||
@ -208,7 +211,7 @@ vector<vector<int>> levelOrder(TreeNode* root) {
|
||||
* [0111.二叉树的最小深度(迭代法)](https://programmercarl.com/0111.二叉树的最小深度.html)
|
||||
* [0222.完全二叉树的节点个数(迭代法)](https://programmercarl.com/0222.完全二叉树的节点个数.html)
|
||||
|
||||
### 二叉树深度
|
||||
#### 二叉树深度
|
||||
|
||||
```CPP
|
||||
int getDepth(TreeNode* node) {
|
||||
@ -217,7 +220,7 @@ int getDepth(TreeNode* node) {
|
||||
}
|
||||
```
|
||||
|
||||
### 二叉树节点数量
|
||||
#### 二叉树节点数量
|
||||
|
||||
```CPP
|
||||
int countNodes(TreeNode* root) {
|
||||
@ -226,7 +229,7 @@ int countNodes(TreeNode* root) {
|
||||
}
|
||||
```
|
||||
|
||||
## 回溯算法
|
||||
### 回溯算法
|
||||
```CPP
|
||||
void backtracking(参数) {
|
||||
if (终止条件) {
|
||||
@ -243,7 +246,7 @@ void backtracking(参数) {
|
||||
|
||||
```
|
||||
|
||||
## 并查集
|
||||
### 并查集
|
||||
|
||||
```CPP
|
||||
int n = 1005; // 根据题意而定
|
||||
@ -278,9 +281,9 @@ void backtracking(参数) {
|
||||
(持续补充ing)
|
||||
## 其他语言版本
|
||||
|
||||
JavaScript:
|
||||
### JavaScript:
|
||||
|
||||
## 二分查找法
|
||||
#### 二分查找法
|
||||
|
||||
使用左闭右闭区间
|
||||
|
||||
@ -322,7 +325,7 @@ var search = function (nums, target) {
|
||||
};
|
||||
```
|
||||
|
||||
## KMP
|
||||
#### KMP
|
||||
|
||||
```javascript
|
||||
var kmp = function (next, s) {
|
||||
@ -340,9 +343,9 @@ var kmp = function (next, s) {
|
||||
}
|
||||
```
|
||||
|
||||
## 二叉树
|
||||
#### 二叉树
|
||||
|
||||
### 深度优先遍历(递归)
|
||||
##### 深度优先遍历(递归)
|
||||
|
||||
二叉树节点定义:
|
||||
|
||||
@ -387,7 +390,7 @@ var postorder = function (root, list) {
|
||||
}
|
||||
```
|
||||
|
||||
### 深度优先遍历(迭代)
|
||||
##### 深度优先遍历(迭代)
|
||||
|
||||
前序遍历(中左右):
|
||||
|
||||
@ -447,7 +450,7 @@ var postorderTraversal = function (root) {
|
||||
};
|
||||
```
|
||||
|
||||
### 广度优先遍历(队列)
|
||||
##### 广度优先遍历(队列)
|
||||
|
||||
```javascript
|
||||
var levelOrder = function (root) {
|
||||
@ -469,7 +472,7 @@ var levelOrder = function (root) {
|
||||
};
|
||||
```
|
||||
|
||||
### 二叉树深度
|
||||
##### 二叉树深度
|
||||
|
||||
```javascript
|
||||
var getDepth = function (node) {
|
||||
@ -478,7 +481,7 @@ var getDepth = function (node) {
|
||||
}
|
||||
```
|
||||
|
||||
### 二叉树节点数量
|
||||
##### 二叉树节点数量
|
||||
|
||||
```javascript
|
||||
var countNodes = function (root) {
|
||||
@ -487,7 +490,7 @@ var countNodes = function (root) {
|
||||
}
|
||||
```
|
||||
|
||||
## 回溯算法
|
||||
#### 回溯算法
|
||||
|
||||
```javascript
|
||||
function backtracking(参数) {
|
||||
@ -505,7 +508,7 @@ function backtracking(参数) {
|
||||
|
||||
```
|
||||
|
||||
## 并查集
|
||||
#### 并查集
|
||||
|
||||
```javascript
|
||||
let n = 1005; // 根据题意而定
|
||||
@ -536,9 +539,9 @@ function backtracking(参数) {
|
||||
}
|
||||
```
|
||||
|
||||
TypeScript:
|
||||
### TypeScript:
|
||||
|
||||
## 二分查找法
|
||||
#### 二分查找法
|
||||
|
||||
使用左闭右闭区间
|
||||
|
||||
@ -580,7 +583,7 @@ var search = function (nums: number[], target: number): number {
|
||||
};
|
||||
```
|
||||
|
||||
## KMP
|
||||
#### KMP
|
||||
|
||||
```typescript
|
||||
var kmp = function (next: number[], s: number): void {
|
||||
@ -598,9 +601,9 @@ var kmp = function (next: number[], s: number): void {
|
||||
}
|
||||
```
|
||||
|
||||
## 二叉树
|
||||
#### 二叉树
|
||||
|
||||
### 深度优先遍历(递归)
|
||||
##### 深度优先遍历(递归)
|
||||
|
||||
二叉树节点定义:
|
||||
|
||||
@ -650,7 +653,7 @@ var postorder = function (root: TreeNode | null, list: number[]): void {
|
||||
}
|
||||
```
|
||||
|
||||
### 深度优先遍历(迭代)
|
||||
##### 深度优先遍历(迭代)
|
||||
|
||||
前序遍历(中左右):
|
||||
|
||||
@ -710,7 +713,7 @@ var postorderTraversal = function (root: TreeNode | null): number[] {
|
||||
};
|
||||
```
|
||||
|
||||
### 广度优先遍历(队列)
|
||||
##### 广度优先遍历(队列)
|
||||
|
||||
```typescript
|
||||
var levelOrder = function (root: TreeNode | null): number[] {
|
||||
@ -732,7 +735,7 @@ var levelOrder = function (root: TreeNode | null): number[] {
|
||||
};
|
||||
```
|
||||
|
||||
### 二叉树深度
|
||||
##### 二叉树深度
|
||||
|
||||
```typescript
|
||||
var getDepth = function (node: TreNode | null): number {
|
||||
@ -741,7 +744,7 @@ var getDepth = function (node: TreNode | null): number {
|
||||
}
|
||||
```
|
||||
|
||||
### 二叉树节点数量
|
||||
##### 二叉树节点数量
|
||||
|
||||
```typescript
|
||||
var countNodes = function (root: TreeNode | null): number {
|
||||
@ -750,7 +753,7 @@ var countNodes = function (root: TreeNode | null): number {
|
||||
}
|
||||
```
|
||||
|
||||
## 回溯算法
|
||||
#### 回溯算法
|
||||
|
||||
```typescript
|
||||
function backtracking(参数) {
|
||||
@ -768,7 +771,7 @@ function backtracking(参数) {
|
||||
|
||||
```
|
||||
|
||||
## 并查集
|
||||
#### 并查集
|
||||
|
||||
```typescript
|
||||
let n: number = 1005; // 根据题意而定
|
||||
@ -801,9 +804,9 @@ function backtracking(参数) {
|
||||
|
||||
Java:
|
||||
|
||||
### Python:
|
||||
|
||||
Python:
|
||||
## 二分查找法
|
||||
#### 二分查找法
|
||||
```python
|
||||
def binarysearch(nums, target):
|
||||
low = 0
|
||||
@ -823,7 +826,7 @@ def binarysearch(nums, target):
|
||||
return -1
|
||||
```
|
||||
|
||||
## KMP
|
||||
#### KMP
|
||||
|
||||
```python
|
||||
def kmp(self, a, s):
|
||||
|
@ -3,8 +3,10 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 动态规划:01背包理论基础(滚动数组)
|
||||
|
||||
|
||||
## 算法公开课
|
||||
|
||||
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[带你学透0-1背包问题!(滚动数组)](https://www.bilibili.com/video/BV1BU4y177kY/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
|
||||
|
@ -3,6 +3,7 @@
|
||||
<img src="../pics/训练营.png" width="1000"/>
|
||||
</a>
|
||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 链表总结篇
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user