diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index 25b81799..8d0cc525 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -425,8 +425,8 @@ public: if (needle.size() == 0) { return 0; } - int next[needle.size()]; - getNext(next, needle); + vector next(needle.size()); + getNext(&next[0], needle); int j = -1; // // 因为next数组里记录的起始位置为-1 for (int i = 0; i < haystack.size(); i++) { // 注意i就从0开始 while(j >= 0 && haystack[i] != needle[j + 1]) { // 不匹配 @@ -524,8 +524,8 @@ public: if (needle.size() == 0) { return 0; } - int next[needle.size()]; - getNext(next, needle); + vector next(needle.size()); + getNext(&next[0], needle); int j = 0; for (int i = 0; i < haystack.size(); i++) { while(j > 0 && haystack[i] != needle[j]) { @@ -1428,4 +1428,3 @@ public int[] GetNext(string needle) - diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index e006caa2..d290f55e 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -285,6 +285,34 @@ class Solution: ### Go + +```go +/** + * @date: 2024 Jan 06 + * @time: 13:44 + * @author: Chris +**/ +// 贪心算法优化版 + +// 记录步骤规则:每超过上一次可达最大范围,需要跳跃一次,次数+1 +// 记录位置:i == lastDistance + 1 +func jump(nums []int) int { + // 根据题目规则,初始位置为nums[0] + lastDistance := 0 // 上一次覆盖范围 + curDistance := 0 // 当前覆盖范围(可达最大范围) + minStep := 0 // 记录最少跳跃次数 + + for i := 0; i < len(nums); i++ { + if i == lastDistance+1 { // 在上一次可达范围+1的位置,记录步骤 + minStep++ // 跳跃次数+1 + lastDistance = curDistance // 记录时才可以更新 + } + curDistance = max(nums[i]+i, curDistance) // 更新当前可达的最大范围 + } + return minStep +} +``` + ```go // 贪心版本一 func jump(nums []int) int { diff --git a/problems/0116.填充每个节点的下一个右侧节点指针.md b/problems/0116.填充每个节点的下一个右侧节点指针.md index 003ef75a..60ea9210 100644 --- a/problems/0116.填充每个节点的下一个右侧节点指针.md +++ b/problems/0116.填充每个节点的下一个右侧节点指针.md @@ -358,7 +358,84 @@ function connect(root: NodePro | null): NodePro | null { }; ``` +```csharp +//递归 +public class Solution { + public Node Connect(Node root) { + if (root == null) { + return null; + } + + ConnectNodes(root.left, root.right); + + return root; + } + private void ConnectNodes(Node node1, Node node2) { + if (node1 == null || node2 == null) { + return; + } + + // 将左子节点的 next 指向右子节点 + node1.next = node2; + + // 递归连接当前节点的左右子节点 + ConnectNodes(node1.left, node1.right); + ConnectNodes(node2.left, node2.right); + + // 连接跨越父节点的两个子树 + ConnectNodes(node1.right, node2.left); + } +} + + +// 迭代 +public class Solution +{ + public Node Connect(Node root) + { + Queue que = new Queue(); + + if (root != null) + { + que.Enqueue(root); + } + + while (que.Count > 0) + { + + var queSize = que.Count; + for (int i = 0; i < queSize; i++) + { + var cur = que.Dequeue(); + + // 当这个节点不是这一层的最后的节点 + if (i != queSize - 1) + { + // 当前节点指向下一个节点 + cur.next = que.Peek(); + } + // 否则指向空 + else + { + cur.next = null; + } + + if (cur.left != null) + { + que.Enqueue(cur.left); + } + if (cur.right != null) + { + que.Enqueue(cur.right); + } + } + } + + return root; + } +} +```

diff --git a/problems/0200.岛屿数量.深搜版.md b/problems/0200.岛屿数量.深搜版.md index a4b93c3d..18442943 100644 --- a/problems/0200.岛屿数量.深搜版.md +++ b/problems/0200.岛屿数量.深搜版.md @@ -389,50 +389,41 @@ function numIslands(grid: string[][]): number { ### Go ```go + +var DIRECTIONS = [4][2]int{{-1, 0}, {0, -1}, {1, 0}, {0, 1}} + 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])) - } + res := 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} + visited := make([][]bool, len(grid)) + for i := 0; i < len(grid); i++ { + visited[i] = make([]bool, len(grid[0])) + } - for len(stack) != 0{ - node := stack[len(stack) - 1] - stack = stack[:len(stack) - 1] + for i, rows := range grid { + for j, v := range rows { + if v == '1' && !visited[i][j] { + res++ + dfs(grid, visited, i, j) + } + } + } - 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}) - } - } - } - } + return res +} - 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++ - } - } - } +func dfs(grid [][]byte, visited [][]bool, i, j int) { + visited[x][y] = true + for _, d := range DIRECTIONS { + x, y := i+d[0], j+d[1] + if x < 0 || x >= len(grid) || y < 0 || y >= len(grid[0]) { + continue + } + if grid[x][y] == '1' && !visited[x][y] { + dfs(grid, visited, x, y) + } + } - return result } ``` diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index d89bf44b..6900e668 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -1046,6 +1046,8 @@ class MyStack() { ### C#: +> 双队列 + ```csharp public class MyStack { Queue queue1; @@ -1080,6 +1082,54 @@ public class MyStack { } ``` +> 单队列 + +```c# +/* + * @lc app=leetcode id=225 lang=csharp + * 版本二:单队列 + * [225] Implement Stack using Queues + */ + +// @lc code=start +public class MyStack { + Queue myQueue; + public MyStack() { + myQueue = new Queue(); + } + + public void Push(int x) { + myQueue.Enqueue(x); + } + + //使用一个队列实现 + public int Pop() { + //一个队列在模拟栈弹出元素的时候只要将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部,此时再去弹出元素就是栈的顺序了。 + for (var i = 0; i < myQueue.Count-1; i++) + { + myQueue.Enqueue(myQueue.Dequeue()); + } + return myQueue.Dequeue(); + } + + //复用Pop()的代码 + public int Top() { + int res = Pop(); + myQueue.Enqueue(res); + return res; + } + + public bool Empty() { + return (myQueue.Count == 0); + } +} + +// @lc code=end + +``` + + + ### PHP: > 双队列 @@ -1203,3 +1253,4 @@ impl MyStack { + diff --git a/problems/1971.寻找图中是否存在路径.md b/problems/1971.寻找图中是否存在路径.md index 27ee9147..132b0181 100644 --- a/problems/1971.寻找图中是否存在路径.md +++ b/problems/1971.寻找图中是否存在路径.md @@ -4,30 +4,28 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

-# 1971. 寻找图中是否存在路径 +# 1971. 寻找图中是否存在路径 [题目链接](https://leetcode.cn/problems/find-if-path-exists-in-graph/) -有一个具有 n个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。 +有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。 请你确定是否存在从顶点 start 开始,到顶点 end 结束的 有效路径 。 -给你数组 edges 和整数 n、start和end,如果从 start 到 end 存在 有效路径 ,则返回 true,否则返回 false 。 - - -![](https://code-thinking-1253855093.file.myqcloud.com/pics/20220705101442.png) +给你数组 edges 和整数 n、start 和 end,如果从 start 到 end 存在 有效路径 ,则返回 true,否则返回 false 。 +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20220705101442.png) 提示: -* 1 <= n <= 2 * 10^5 -* 0 <= edges.length <= 2 * 10^5 -* edges[i].length == 2 -* 0 <= ui, vi <= n - 1 -* ui != vi -* 0 <= start, end <= n - 1 -* 不存在双向边 -* 不存在指向顶点自身的边 +- 1 <= n <= 2 \* 10^5 +- 0 <= edges.length <= 2 \* 10^5 +- edges[i].length == 2 +- 0 <= ui, vi <= n - 1 +- ui != vi +- 0 <= start, end <= n - 1 +- 不存在双向边 +- 不存在指向顶点自身的边 ## 思路 @@ -70,7 +68,7 @@ void join(int u, int v) { } ``` -以上模板中,只要修改 n 大小就可以,本题n不会超过2 * 10^5。 +以上模板中,只要修改 n 大小就可以,本题 n 不会超过 2 \* 10^5。 并查集主要有三个功能。 @@ -80,17 +78,17 @@ void join(int u, int v) { 简单介绍并查集之后,我们再来看一下这道题目。 -为什么说这道题目是并查集基础题目,题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。 +为什么说这道题目是并查集基础题目,题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。 -如何算是同一个集合呢,有边连在一起,就算是一个集合。 +如何算是同一个集合呢,有边连在一起,就算是一个集合。 -此时我们就可以直接套用并查集模板。 +此时我们就可以直接套用并查集模板。 -使用join(int u, int v)将每条边加入到并查集。 +使用 join(int u, int v)将每条边加入到并查集。 -最后 isSame(int u, int v) 判断是否是同一个根 就可以了。 +最后 isSame(int u, int v) 判断是否是同一个根 就可以了。 -C++代码如下: +C++代码如下: ```CPP class Solution { @@ -191,7 +189,7 @@ class Solution { ### Python: -PYTHON并查集解法如下: +PYTHON 并查集解法如下: ```PYTHON class Solution: @@ -206,6 +204,85 @@ class Solution: return find(source) == find(destination) ``` +### Javascript: + +Javascript 并查集解法如下: + +```Javascript +class unionF{ + constructor(n){ + this.count = n + this.roots = new Array(n).fill(0).map((item,index)=>index) + } + + findRoot(x){ + if(this.roots[x]!==x){ + this.roots[x] = this.findRoot(this.roots[x]) + } + return this.roots[x] + } + + union(x,y){ + const rx = this.findRoot(x) + const ry = this.findRoot(y) + this.roots[rx] = ry + this.count-- + } + + isConnected(x,y){ + return this.findRoot(x)===this.findRoot(y) + } +} + +var validPath = function(n, edges, source, destination) { + const UF = new unionF(n) + for(const [s,t] of edges){ + UF.union(s,t) + } + return UF.isConnected(source,destination) +}; +``` + +Javascript 双向 bfs 解法如下: + +```Javascript +var validPath = function(n, edges, source, destination) { + const graph = new Array(n).fill(0).map(()=>[]) + for(const [s,t] of edges){ + graph[s].push(t) + graph[t].push(s) + } + + const visited = new Array(n).fill(false) + function bfs(start,end,graph){ + const startq = [start] + const endq = [end] + while(startq.length&&endq.length){ + const slen = startq.length + for(let i = 0;i diff --git a/problems/二叉树理论基础.md b/problems/二叉树理论基础.md index e2c6d83c..50d592a2 100644 --- a/problems/二叉树理论基础.md +++ b/problems/二叉树理论基础.md @@ -302,9 +302,19 @@ impl TreeNode { } } } -``` +``` +```c# +public class TreeNode +{ + public int val; + public TreeNode left; + public TreeNode right; + public TreeNode(int x) { val = x; } +} +```

+ diff --git a/problems/二叉树的递归遍历.md b/problems/二叉树的递归遍历.md index 92a8341f..edd55aad 100644 --- a/problems/二叉树的递归遍历.md +++ b/problems/二叉树的递归遍历.md @@ -623,3 +623,4 @@ public void Traversal(TreeNode cur, IList res) +