diff --git a/README.md b/README.md index d3b4fe66..bf55a004 100644 --- a/README.md +++ b/README.md @@ -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) (持续更新中....) diff --git a/problems/0017.电话号码的字母组合.md b/problems/0017.电话号码的字母组合.md index b3ba1e5e..90296efd 100644 --- a/problems/0017.电话号码的字母组合.md +++ b/problems/0017.电话号码的字母组合.md @@ -694,6 +694,44 @@ object Solution { } ``` +### Ruby +```ruby +def letter_combinations(digits) + letter_map = { + 2 => ['a','b','c'], + 3 => ['d','e','f'], + 4 => ['g','h','i'], + 5 => ['j','k','l'], + 6 => ['m','n','o'], + 7 => ['p','q','r','s'], + 8 => ['t','u','v'], + 9 => ['w','x','y','z'] + } + + result = [] + path = [] + + return result if digits.size == 0 + + backtracking(result, letter_map, digits.split(''), path, 0) + result +end + +def backtracking(result, letter_map, digits, path, index) + if path.size == digits.size + result << path.join('') + return + end + + hash[digits[index].to_i].each do |chr| + path << chr + #index + 1代表处理下一个数字 + backtracking(result, letter_map, digits, path, index + 1) + #回溯,撤销处理过的数字 + path.pop + end +end +```
diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
index e5266cd9..b4128166 100644
--- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
+++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
@@ -739,6 +739,60 @@ class Solution {
}
```
+### C
+```c
+int searchLeftBorder(int *nums, int numsSize, int target) {
+ int left = 0, right = numsSize - 1;
+ // 记录leftBorder没有被赋值的情况
+ int leftBorder = -1;
+ // 边界为[left, right]
+ while (left <= right) {
+ // 更新middle值,等同于middle = (left + right) / 2
+ int middle = left + ((right - left) >> 1);
+ // 若当前middle所指为target,将左边界设为middle,并向左继续寻找左边界
+ if (nums[middle] == target) {
+ leftBorder = middle;
+ right = middle - 1;
+ } else if (nums[middle] > target) {
+ right = middle - 1;
+ } else {
+ left = middle + 1;
+ }
+ }
+ return leftBorder;
+}
+int searchRightBorder(int *nums, int numsSize, int target) {
+ int left = 0, right = numsSize - 1;
+ // 记录rightBorder没有被赋值的情况
+ int rightBorder = -1;
+ while (left <= right) {
+ int middle = left + ((right - left) >> 1);
+ // 若当前middle所指为target,将右边界设为middle,并向右继续寻找右边界
+ if (nums[middle] == target) {
+ rightBorder = middle;
+ left = middle + 1;
+ } else if (nums[middle] > target) {
+ right = middle - 1;
+ } else {
+ left = middle + 1;
+ }
+ }
+ return rightBorder;
+}
+
+int* searchRange(int* nums, int numsSize, int target, int* returnSize){
+ int leftBorder = searchLeftBorder(nums, numsSize, target);
+ int rightBorder = searchRightBorder(nums, numsSize, target);
+
+ // 定义返回数组及数组大小
+ *returnSize = 2;
+ int *resNums = (int*)malloc(sizeof(int) * 2);
+ resNums[0] = leftBorder;
+ resNums[1] = rightBorder;
+ return resNums;
+}
+```
+
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
diff --git a/problems/0518.零钱兑换II.md b/problems/0518.零钱兑换II.md
index 7c9f0fce..5c6efdcb 100644
--- a/problems/0518.零钱兑换II.md
+++ b/problems/0518.零钱兑换II.md
@@ -184,7 +184,7 @@ public:
* 空间复杂度: O(m)
-是不是发现代码如此精简,哈哈
+是不是发现代码如此精简
## 总结
diff --git a/problems/0657.机器人能否返回原点.md b/problems/0657.机器人能否返回原点.md
index f0d33391..ef587391 100644
--- a/problems/0657.机器人能否返回原点.md
+++ b/problems/0657.机器人能否返回原点.md
@@ -31,7 +31,7 @@
## 思路
-这道题目还是挺简单的,大家不要想复杂了,一波哈希法又一波图论算法啥的,哈哈。
+这道题目还是挺简单的,大家不要想复杂了,一波哈希法又一波图论算法之类的。
其实就是,x,y坐标,初始为0,然后:
* if (moves[i] == 'U') y++;
diff --git a/problems/0695.岛屿的最大面积.md b/problems/0695.岛屿的最大面积.md
index 894f3a75..74470ae5 100644
--- a/problems/0695.岛屿的最大面积.md
+++ b/problems/0695.岛屿的最大面积.md
@@ -390,6 +390,7 @@ class Solution:
if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]):
self.dfs(grid, visited, new_x, new_y)
```
+
### JavaScript
```javascript
var maxAreaOfIsland = function (grid) {
@@ -428,6 +429,145 @@ var maxAreaOfIsland = function (grid) {
```
+### Rust
+
+dfs: 版本一
+
+```rust
+impl Solution {
+ const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)];
+
+ pub fn max_area_of_island(grid: Vec
参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md
index 2b5a1925..76553151 100644
--- a/problems/0072.编辑距离.md
+++ b/problems/0072.编辑距离.md
@@ -41,7 +41,7 @@ exection -> execution (插入 'u')
* word1 和 word2 由小写英文字母组成
## 算法公开课
-**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划终极绝杀! LeetCode:72.编辑距离](https://www.bilibili.com/video/BV1we4y157wB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
+**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划终极绝杀! LeetCode:72.编辑距离](https://www.bilibili.com/video/BV1qv4y1q78f/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。
## 思路
@@ -465,4 +465,3 @@ impl Solution {
-
diff --git a/problems/0077.组合.md b/problems/0077.组合.md
index 8d448739..a7f00ffe 100644
--- a/problems/0077.组合.md
+++ b/problems/0077.组合.md
@@ -764,6 +764,35 @@ object Solution {
}
```
+### Ruby
+
+```ruby
+
+def combine(n, k)
+ result = []
+ path = []
+ backtracking(result, path, n, 1, k)
+ return result
+end
+
+#剪枝优化
+def backtracking(result, path, n, j, k)
+ if path.size == k
+ result << path.map {|item| item}
+ return
+ end
+
+ for i in j..(n-(k - path.size)) + 1
+ #处理节点
+ path << i
+ backtracking(result, path, n, i + 1, k)
+ #回溯,撤销处理过的节点
+ path.pop
+ end
+end
+
+```
+
diff --git a/problems/0096.不同的二叉搜索树.md b/problems/0096.不同的二叉搜索树.md
index 8d58cc5a..d109165b 100644
--- a/problems/0096.不同的二叉搜索树.md
+++ b/problems/0096.不同的二叉搜索树.md
@@ -159,7 +159,7 @@ public:
可以看出我依然还是用动规五部曲来进行分析,会把题目的方方面面都覆盖到!
-**而且具体这五部分析是我自己平时总结的经验,找不出来第二个的,可能过一阵子 其他题解也会有动规五部曲了,哈哈**。
+**而且具体这五部分析是我自己平时总结的经验,找不出来第二个的,可能过一阵子 其他题解也会有动规五部曲了**。
当时我在用动规五部曲讲解斐波那契的时候,一些录友和我反应,感觉讲复杂了。
diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md
index a48ec065..0a64266e 100644
--- a/problems/0098.验证二叉搜索树.md
+++ b/problems/0098.验证二叉搜索树.md
@@ -249,9 +249,9 @@ public:
这道题目是一个简单题,但对于没接触过的同学还是有难度的。
-所以初学者刚开始学习算法的时候,看到简单题目没有思路很正常,千万别怀疑自己智商,学习过程都是这样的,大家智商都差不多,哈哈。
+所以初学者刚开始学习算法的时候,看到简单题目没有思路很正常,千万别怀疑自己智商,学习过程都是这样的,大家智商都差不多。
-只要把基本类型的题目都做过,总结过之后,思路自然就开阔了。
+只要把基本类型的题目都做过,总结过之后,思路自然就开阔了,加油💪
## 其他语言版本
diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md
index ca73e9f7..80ac2843 100644
--- a/problems/0131.分割回文串.md
+++ b/problems/0131.分割回文串.md
@@ -300,7 +300,7 @@ public:
所以本题应该是一道hard题目了。
-**可能刷过这道题目的录友都没感受到自己原来克服了这么多难点,就把这道题目AC了**,这应该叫做无招胜有招,人码合一,哈哈哈。
+**可能刷过这道题目的录友都没感受到自己原来克服了这么多难点,就把这道题目AC了**,这应该叫做无招胜有招,人码合一。
diff --git a/problems/0142.环形链表II.md b/problems/0142.环形链表II.md
index d20101a7..a643fd70 100644
--- a/problems/0142.环形链表II.md
+++ b/problems/0142.环形链表II.md
@@ -187,7 +187,7 @@ public:
## 总结
-这次可以说把环形链表这道题目的各个细节,完完整整的证明了一遍,说这是全网最详细讲解不为过吧,哈哈。
+这次可以说把环形链表这道题目的各个细节,完完整整的证明了一遍,说这是全网最详细讲解不为过吧。
## 其他语言版本
diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md
index 0c1a526f..111c07e4 100644
--- a/problems/0151.翻转字符串里的单词.md
+++ b/problems/0151.翻转字符串里的单词.md
@@ -311,7 +311,7 @@ class Solution {
```
```java
-//解法三:双反转+移位,在原始数组上进行反转。空间复杂度O(1)
+//解法三:双反转+移位,String 的 toCharArray() 方法底层会 new 一个和原字符串相同大小的 char 数组,空间复杂度:O(n)
class Solution {
/**
* 思路:
diff --git a/problems/0200.岛屿数量.广搜版.md b/problems/0200.岛屿数量.广搜版.md
index 5acdf6e2..e8ed60db 100644
--- a/problems/0200.岛屿数量.广搜版.md
+++ b/problems/0200.岛屿数量.广搜版.md
@@ -276,6 +276,47 @@ var numIslands = function (grid) {
};
```
+### 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
diff --git a/problems/0200.岛屿数量.深搜版.md b/problems/0200.岛屿数量.深搜版.md
index b8f2c992..c7649971 100644
--- a/problems/0200.岛屿数量.深搜版.md
+++ b/problems/0200.岛屿数量.深搜版.md
@@ -219,7 +219,7 @@ class Solution {
}
```
-Python:
+### Python:
```python
# 版本一
@@ -312,6 +312,92 @@ var numIslands = function (grid) {
};
```
+### Go
+
+```go
+func numIslands(grid [][]byte) int {
+ // 用1标记已访问
+ visited := make([][]int, len(grid))
+ for i := 0; i < len(visited); i++{
+ visited[i] = make([]int, len(grid[0]))
+ }
+
+ var bfs func(x, y int)
+ bfs = func(x, y int){
+ stack := make([][]int, 0)
+ stack = append(stack, []int{x, y})
+ moveX := []int{1, -1, 0, 0}
+ moveY := []int{0, 0, 1, -1}
+
+ for len(stack) != 0{
+ node := stack[len(stack) - 1]
+ stack = stack[:len(stack) - 1]
+
+ for i := 0; i < 4; i++{
+ dx := moveX[i] + node[0]
+ dy := moveY[i] + node[1]
+ if dx < 0 || dx >= len(grid) || dy < 0 || dy >= len(grid[0]) || visited[dx][dy] == 1{
+ continue
+ }
+ visited[dx][dy] = 1
+ if grid[dx][dy] == '1'{
+ stack = append(stack, []int{dx,dy})
+ }
+ }
+ }
+ }
+
+ result := 0
+ for i := 0; i < len(grid); i++{
+ for j := 0; j < len(grid[0]); j++{
+ if visited[i][j] == 0 && grid[i][j] == '1'{
+ bfs(i, j)
+ visited[i][j] = 1
+ result++
+ }
+ }
+ }
+
+ 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
diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md
index 1042b5a7..265bbb5b 100644
--- a/problems/0701.二叉搜索树中的插入操作.md
+++ b/problems/0701.二叉搜索树中的插入操作.md
@@ -82,7 +82,7 @@ if (root == NULL) {
此时要明确,需要遍历整棵树么?
-别忘了这是搜索树,遍历整棵搜索树简直是对搜索树的侮辱,哈哈。
+别忘了这是搜索树,遍历整棵搜索树简直是对搜索树的侮辱。
搜索树是有方向了,可以根据插入元素的数值,决定递归方向。
diff --git a/problems/0797.所有可能的路径.md b/problems/0797.所有可能的路径.md
index 6b47c42e..bcce9314 100644
--- a/problems/0797.所有可能的路径.md
+++ b/problems/0797.所有可能的路径.md
@@ -217,6 +217,7 @@ class Solution:
self.path.pop() # 回溯
```
+
### JavaScript
```javascript
var allPathsSourceTarget = function(graph) {
@@ -240,6 +241,58 @@ var allPathsSourceTarget = function(graph) {
```
+### Go
+
+```go
+func allPathsSourceTarget(graph [][]int) [][]int {
+ result := make([][]int, 0)
+
+ var dfs func(path []int, step int)
+ dfs = func(path []int, step int){
+ // 从0遍历到length-1
+ if step == len(graph) - 1{
+ tmp := make([]int, len(path))
+ copy(tmp, path)
+ result = append(result, tmp)
+ return
+ }
+
+ for i := 0; i < len(graph[step]); i++{
+ next := append(path, graph[step][i])
+ dfs(next, graph[step][i])
+ }
+ }
+ // 从0开始,开始push 0进去
+ dfs([]int{0}, 0)
+ return result
+}
+
+```
+
+### Rust
+
+
+```rust
+impl Solution {
+ pub fn all_paths_source_target(graph: Vec