From 9b9adf6100bb2d8b3e2703b5f573af05a8890d15 Mon Sep 17 00:00:00 2001 From: eat to 160 pounds <2915390277@qq.com> Date: Sat, 13 Jul 2024 15:10:24 +0800 Subject: [PATCH 01/22] =?UTF-8?q?feat(0309):=20=E5=8F=A6=E4=B8=80=E7=A7=8D?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=AE=9A=E4=B9=89=E6=80=9D=E8=B7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...09.最佳买卖股票时机含冷冻期.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md index 5a38111a..95689a48 100644 --- a/problems/0309.最佳买卖股票时机含冷冻期.md +++ b/problems/0309.最佳买卖股票时机含冷冻期.md @@ -359,6 +359,26 @@ func max(a, b int) int { ### Javascript: +> 不同的状态定义 感觉更容易理解些 +```javascript +function maxProfit(prices) { + // 第i天状态 持股 卖出 非冷冻期(不持股) 处于冷冻期 + const dp = new Array(prices.length).fill(0).map(() => [0, 0, 0, 0]); + dp[0][0] = -prices[0]; + for (let i = 1; i < prices.length; i++) { + // 持股 + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][2] - prices[i]); + // 卖出 + dp[i][1] = dp[i - 1][0] + prices[i]; + // 非冷冻期(不持股) + dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1]); + // 冷冻期(上一天卖出) + dp[i][3] = dp[i - 1][1]; + } + return Math.max(...dp.pop()); +}; +``` + ```javascript const maxProfit = (prices) => { if(prices.length < 2) { From afbcb1d98bd5a0e40f9f65d1ced60e62c286fbf2 Mon Sep 17 00:00:00 2001 From: XZY <1214807740@qq.com> Date: Mon, 15 Jul 2024 12:14:43 +0800 Subject: [PATCH 02/22] =?UTF-8?q?Update=20121.=20=E4=B9=B0=E5=8D=96?= =?UTF-8?q?=E8=82=A1=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0121.买卖股票的最佳时机.md | 22 +++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index e9aea0e6..df586ff9 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -466,7 +466,7 @@ function maxProfit(prices: number[]): number { }; ``` -> 动态规划 +> 动态规划:版本一 ```typescript function maxProfit(prices: number[]): number { @@ -487,6 +487,26 @@ function maxProfit(prices: number[]): number { }; ``` +> 动态规划:版本二 + +```typescript +// dp[i][0] 表示第i天持有股票所得最多现金 +// dp[i][1] 表示第i天不持有股票所得最多现金 +function maxProfit(prices: number[]): number { + const dp:number[][] = Array(2).fill(0).map(item => Array(2)); + dp[0][0] = -prices[0]; + dp[0][1] = 0; + + for (let i = 1; i < prices.length; i++) { + dp[i % 2][0] = Math.max(dp[(i - 1) % 2][0], -prices[i]); + dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]); + } + + // 返回不持有股票的最大现金 + return dp[(prices.length-1) % 2][1]; +}; +``` + ### C#: > 贪心法 From 06a089e780e1be6206e58ed052b6615ee0cb7dc2 Mon Sep 17 00:00:00 2001 From: Jack Lin Date: Mon, 15 Jul 2024 15:25:31 +0800 Subject: [PATCH 03/22] =?UTF-8?q?0406.=E6=A0=B9=E6=8D=AE=E8=BA=AB=E9=AB=98?= =?UTF-8?q?=E9=87=8D=E5=BB=BA=E9=98=9F=E5=88=97.md:=20Fix=20typo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0406.根据身高重建队列.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index b7e94543..d92a7f3f 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -87,7 +87,7 @@ 回归本题,整个插入过程如下: 排序完的people: -[[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]] +[[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]] 插入的过程: * 插入[7,0]:[[7,0]] From 3848c96acd298f3b3593bb78eeb91dd1377a7d82 Mon Sep 17 00:00:00 2001 From: kimoge <1579457263@qq.com> Date: Mon, 15 Jul 2024 23:12:22 +0800 Subject: [PATCH 04/22] =?UTF-8?q?=E6=9B=B4=E6=96=B00097=5F=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0Python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0097.小明逛公园.md | 64 +++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/problems/kamacoder/0097.小明逛公园.md b/problems/kamacoder/0097.小明逛公园.md index 5465c356..e8d92cc2 100644 --- a/problems/kamacoder/0097.小明逛公园.md +++ b/problems/kamacoder/0097.小明逛公园.md @@ -339,7 +339,7 @@ int main() { } } -``` +``` ## 空间优化 @@ -426,6 +426,68 @@ floyd算法的时间复杂度相对较高,适合 稠密图且源点较多的 ### Python +基于三维数组的Floyd + +```python +if __name__ == '__main__': + max_int = 10005 # 设置最大路径,因为边最大距离为10^4 + + n, m = map(int, input().split()) + + grid = [[[max_int] * (n+1) for _ in range(n+1)] for _ in range(n+1)] # 初始化三维dp数组 + + for _ in range(m): + p1, p2, w = map(int, input().split()) + grid[p1][p2][0] = w + grid[p2][p1][0] = w + + # 开始floyd + for k in range(1, n+1): + for i in range(1, n+1): + for j in range(1, n+1): + grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1] + grid[k][j][k-1]) + + # 输出结果 + z = int(input()) + for _ in range(z): + start, end = map(int, input().split()) + if grid[start][end][n] == max_int: + print(-1) + else: + print(grid[start][end][n]) +``` + +基于二维数组的Floyd + +```python +if __name__ == '__main__': + max_int = 10005 # 设置最大路径,因为边最大距离为10^4 + + n, m = map(int, input().split()) + + grid = [[max_int]*(n+1) for _ in range(n+1)] # 初始化二维dp数组 + + for _ in range(m): + p1, p2, val = map(int, input().split()) + grid[p1][p2] = val + grid[p2][p1] = val + + # 开始floyd + for k in range(1, n+1): + for i in range(1, n+1): + for j in range(1, n+1): + grid[i][j] = min(grid[i][j], grid[i][k] + grid[k][j]) + + # 输出结果 + z = int(input()) + for _ in range(z): + start, end = map(int, input().split()) + if grid[start][end] == max_int: + print(-1) + else: + print(grid[start][end]) +``` + ### Go ### Rust From 42987012694e2370572ed30ff5ff6f201e613c02 Mon Sep 17 00:00:00 2001 From: markwang Date: Tue, 16 Jul 2024 10:33:07 +0800 Subject: [PATCH 05/22] =?UTF-8?q?106.=E4=BB=8E=E4=B8=AD=E5=BA=8F=E4=B8=8E?= =?UTF-8?q?=E5=90=8E=E5=BA=8F=E9=81=8D=E5=8E=86=E5=BA=8F=E5=88=97=E6=9E=84?= =?UTF-8?q?=E9=80=A0=E4=BA=8C=E5=8F=89=E6=A0=91=E5=A2=9E=E5=8A=A0Go?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...序与后序遍历序列构造二叉树.md | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/problems/0106.从中序与后序遍历序列构造二叉树.md b/problems/0106.从中序与后序遍历序列构造二叉树.md index 3518343f..bde61a75 100644 --- a/problems/0106.从中序与后序遍历序列构造二叉树.md +++ b/problems/0106.从中序与后序遍历序列构造二叉树.md @@ -794,6 +794,60 @@ func rebuild(inorder []int, postorder []int, rootIdx int, l, r int) *TreeNode { } ``` +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func buildTree(inorder []int, postorder []int) *TreeNode { + if len(postorder) == 0 { + return nil + } + + // 后序遍历数组最后一个元素,就是当前的中间节点 + rootValue := postorder[len(postorder)-1] + root := &TreeNode{Val:rootValue} + + // 叶子结点 + if len(postorder) == 1 { + return root + } + + // 找到中序遍历的切割点 + var delimiterIndex int + for delimiterIndex = 0; delimiterIndex < len(inorder); delimiterIndex++ { + if inorder[delimiterIndex] == rootValue { + break; + } + } + + // 切割中序数组 + // 左闭右开区间:[0, delimiterIndex) + leftInorder := inorder[:delimiterIndex] + // [delimiterIndex + 1, end) + rightInorder := inorder[delimiterIndex+1:] + + // postorder 舍弃末尾元素 + postorder = postorder[:len(postorder)-1] + + // 切割后序数组 + // 依然左闭右开,注意这里使用了左中序数组大小作为切割点 + // [0, len(leftInorder)) + leftPostorder := postorder[:len(leftInorder)] + // [len(leftInorder), end) + rightPostorder := postorder[len(leftInorder):] + + root.Left = buildTree(leftInorder, leftPostorder) + root.Right = buildTree(rightInorder, rightPostorder) + + return root +} +``` + 105 从前序与中序遍历序列构造二叉树 ```go @@ -829,6 +883,60 @@ func build(pre []int, in []int, root int, l, r int) *TreeNode { } ``` +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func buildTree(preorder []int, inorder []int) *TreeNode { + if len(preorder) == 0 { + return nil + } + + // 前序遍历数组第一个元素,就是当前的中间节点 + rootValue := preorder[0] + root := &TreeNode{Val:rootValue} + + // 叶子结点 + if len(preorder) == 1 { + return root + } + + // 找到中序遍历的切割点 + var delimiterIndex int + for delimiterIndex = 0; delimiterIndex < len(inorder); delimiterIndex++ { + if inorder[delimiterIndex] == rootValue { + break + } + } + + // 切割中序数组 + // 左闭右开区间:[0, delimiterIndex) + leftInorder := inorder[:delimiterIndex] + // [delimiterIndex + 1, end) + rightInorder := inorder[delimiterIndex+1:] + + // preorder 舍弃首位元素 + preorder = preorder[1:] + + // 切割前序数组 + // 依然左闭右开,注意这里使用了左中序数组大小作为切割点 + // [0, len(leftInorder)) + leftPreorder := preorder[:len(leftInorder)] + // [len(leftInorder), end) + rightPreorder := preorder[len(leftInorder):] + + root.Left = buildTree(leftPreorder, leftInorder) + root.Right = buildTree(rightPreorder, rightInorder) + + return root +} +``` + ### JavaScript From 5db796f3e2643db83e6829a0d7cfb459bb9781b5 Mon Sep 17 00:00:00 2001 From: kimoge <1579457263@qq.com> Date: Wed, 17 Jul 2024 09:53:30 +0800 Subject: [PATCH 06/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910099.=E5=B2=9B=E5=B1=BF=E7=9A=84=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E6=B7=B1=E6=90=9C=EF=BC=8C=E6=B7=BB=E5=8A=A0Python3=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0099.岛屿的数量深搜.md | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/problems/kamacoder/0099.岛屿的数量深搜.md b/problems/kamacoder/0099.岛屿的数量深搜.md index 37f7086a..94ce8d5b 100644 --- a/problems/kamacoder/0099.岛屿的数量深搜.md +++ b/problems/kamacoder/0099.岛屿的数量深搜.md @@ -185,6 +185,100 @@ int main() { ### Python +版本一 + +```python +direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:上、右、下、左 + + +def dfs(grid, visited, x, y): + """ + 对一块陆地进行深度优先遍历并标记 + """ + for i, j in direction: + next_x = x + i + next_y = y + j + # 下标越界,跳过 + if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]): + continue + # 未访问的陆地,标记并调用深度优先搜索 + if not visited[next_x][next_y] and grid[next_x][next_y] == 1: + visited[next_x][next_y] = True + dfs(grid, visited, next_x, next_y) + + +if __name__ == '__main__': + # 版本一 + n, m = map(int, input().split()) + + # 邻接矩阵 + grid = [] + for i in range(n): + grid.append(list(map(int, input().split()))) + + # 访问表 + visited = [[False] * m for _ in range(n)] + + res = 0 + for i in range(n): + for j in range(m): + # 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。 + if grid[i][j] == 1 and not visited[i][j]: + res += 1 + visited[i][j] = True + dfs(grid, visited, i, j) + + print(res) +``` + +版本二 + +```python +direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:上、右、下、左 + + +def dfs(grid, visited, x, y): + """ + 对一块陆地进行深度优先遍历并标记 + """ + # 与版本一的差别,在调用前增加判断终止条件 + if visited[x][y] or grid[x][y] == 0: + return + visited[x][y] = True + + for i, j in direction: + next_x = x + i + next_y = y + j + # 下标越界,跳过 + if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]): + continue + # 由于判断条件放在了方法首部,此处直接调用dfs方法 + dfs(grid, visited, next_x, next_y) + + +if __name__ == '__main__': + # 版本二 + n, m = map(int, input().split()) + + # 邻接矩阵 + grid = [] + for i in range(n): + grid.append(list(map(int, input().split()))) + + # 访问表 + visited = [[False] * m for _ in range(n)] + + res = 0 + for i in range(n): + for j in range(m): + # 判断:如果当前节点是陆地,res+1并标记访问该节点,使用深度搜索标记相邻陆地。 + if grid[i][j] == 1 and not visited[i][j]: + res += 1 + dfs(grid, visited, i, j) + + print(res) +``` + ### Go ### Rust From 750ce672ea5ff0dafe96cde854d8f0aeedacfb51 Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Wed, 17 Jul 2024 14:05:50 +0800 Subject: [PATCH 07/22] =?UTF-8?q?fix:=20=E5=8D=A1=E7=A0=81=E7=BD=910106.?= =?UTF-8?q?=E5=B2=9B=E5=B1=BF=E7=9A=84=E5=91=A8=E9=95=BF=20=E8=A1=A8?= =?UTF-8?q?=E8=BF=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0106.岛屿的周长.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/kamacoder/0106.岛屿的周长.md b/problems/kamacoder/0106.岛屿的周长.md index 34063039..48400a95 100644 --- a/problems/kamacoder/0106.岛屿的周长.md +++ b/problems/kamacoder/0106.岛屿的周长.md @@ -66,7 +66,7 @@ ![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240524120105.png) -该录友的下边空格出界了,则说明找到一条边。 +该陆地的下边空格出界了,则说明找到一条边。 C++代码如下:(详细注释) From 7aa230ed40e7583a61ec6b6fb38500b17c0dfe27 Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Wed, 17 Jul 2024 14:13:19 +0800 Subject: [PATCH 08/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910098.=E6=89=80=E6=9C=89=E5=8F=AF=E8=BE=BE=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=20JS=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0098.所有可达路径.md | 146 +++++++++++++++++- 1 file changed, 142 insertions(+), 4 deletions(-) diff --git a/problems/kamacoder/0098.所有可达路径.md b/problems/kamacoder/0098.所有可达路径.md index 073d1a2e..3281303d 100644 --- a/problems/kamacoder/0098.所有可达路径.md +++ b/problems/kamacoder/0098.所有可达路径.md @@ -75,7 +75,7 @@ ## 插曲 -------------- +------------- 本题和力扣 [797.所有可能的路径](https://leetcode.cn/problems/all-paths-from-source-to-target/description/) 是一样的,录友了解深度优先搜索之后,这道题目就是模板题,是送分题。 @@ -475,7 +475,7 @@ public class Main { } } } -``` +``` #### 邻接表写法 ```java @@ -564,7 +564,7 @@ def main(): if __name__ == "__main__": main() -``` +``` #### 邻接表写法 ``` python @@ -608,6 +608,145 @@ if __name__ == "__main__": ### Javascript +#### 邻接矩阵写法 + +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async ()=>(await iter.next()).value; + + +let graph; +let N, M; +// 收集符合条件的路径 +let result = []; +// 1节点到终点的路径 +let path = []; + +// 创建邻接矩阵,初始化邻接矩阵 +async function initGraph(){ + let line; + + line = await readline(); + [N, M] = line.split(' ').map(i => parseInt(i)) + graph = new Array(N + 1).fill(0).map(() => new Array(N + 1).fill(0)) + + while(M--){ + line = await readline() + const strArr = line ? line.split(' ').map(i => parseInt(i)) : undefined + strArr ? graph[strArr[0]][strArr[1]] = 1 : null + } +}; + +// 深度搜索 +function dfs(graph, x, n){ + // 当前遍历节点为x, 到达节点为n + if(x == n){ + result.push([...path]) + return + } + for(let i = 1 ; i <= n ; i++){ + if(graph[x][i] == 1){ + path.push(i) + dfs(graph, i, n ) + path.pop(i) + } + } +}; + +(async function(){ + // 创建邻接矩阵,初始化邻接矩阵 + await initGraph(); + + // 从节点1开始深度搜索 + path.push(1); + + // 深度搜索 + dfs(graph, 1, N ); + + // 输出 + if(result.length > 0){ + result.forEach(i => { + console.log(i.join(' ')) + }) + }else{ + console.log(-1) + } + +})(); + +``` + + + +#### 邻接表写法 + +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph; +let N, M; + +// 收集符合条件的路径 +let result = []; +// 1节点到终点的路径 +let path = []; + +// 创建邻接表,初始化邻接表 +async function initGraph() { + let line; + line = await readline(); + [N, M] = line.split(' ').map(i => parseInt(i)) + graph = new Array(N + 1).fill(0).map(() => new Array()) + + while (line = await readline()) { + const strArr = line.split(' ').map(i => parseInt(i)) + strArr ? graph[strArr[0]].push(strArr[1]) : null + } +}; + +// 深度搜索 +async function dfs(graph, x, n) { + // 当前遍历节点为x, 到达节点为n + if (x == n) { + result.push([...path]) + return + } + + graph[x].forEach(i => { + path.push(i) + dfs(graph, i, n) + path.pop(i) + }) +}; + +(async function () { + // 创建邻接表,初始化邻接表 + await initGraph(); + + // 从节点1开始深度搜索 + path.push(1); + + // 深度搜索 + dfs(graph, 1, N); + + // 输出 + if (result.length > 0) { + result.forEach(i => { + console.log(i.join(' ')) + }) + } else { + console.log(-1) + } +})(); +``` + ### TypeScript ### PhP @@ -628,4 +767,3 @@ if __name__ == "__main__": - From 08a437eb3a2114316b4f4881d2311dcf983c7e08 Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Wed, 17 Jul 2024 14:20:18 +0800 Subject: [PATCH 09/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910099.=E5=B2=9B=E5=B1=BF=E7=9A=84=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E5=B9=BF=E6=90=9C=200099.=E5=B2=9B=E5=B1=BF=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E6=B7=B1=E6=90=9C=20JS=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0099.岛屿的数量广搜.md | 81 +++++++++++++++++++ .../kamacoder/0099.岛屿的数量深搜.md | 75 +++++++++++++++++ 2 files changed, 156 insertions(+) diff --git a/problems/kamacoder/0099.岛屿的数量广搜.md b/problems/kamacoder/0099.岛屿的数量广搜.md index fc7f38e9..b9bdb796 100644 --- a/problems/kamacoder/0099.岛屿的数量广搜.md +++ b/problems/kamacoder/0099.岛屿的数量广搜.md @@ -198,6 +198,87 @@ int main() { ### Javascript +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph +let N, M +let visited +let result = 0 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] + +// 读取输入,初始化地图 +const initGraph = async () => { + let line = await readline(); + [N, M] = line.split(' ').map(Number); + graph = new Array(N).fill(0).map(() => new Array(M).fill(0)) + visited = new Array(N).fill(false).map(() => new Array(M).fill(false)) + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + for (let j = 0; j < M; j++) { + graph[i][j] = line[j] + } + } +} + + +/** + * @description: 从(x, y)开始广度优先遍历 + * @param {*} graph 地图 + * @param {*} visited 访问过的节点 + * @param {*} x 开始搜索节点的下标 + * @param {*} y 开始搜索节点的下标 + * @return {*} + */ +const bfs = (graph, visited, x, y) => { + let queue = [] + queue.push([x, y]) + visited[x][y] = true //只要加入队列就立刻标记为访问过 + + while (queue.length) { + let [x, y] = queue.shift() + for (let i = 0; i < 4; i++) { + let nextx = x + dir[i][0] + let nexty = y + dir[i][1] + if(nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue + if(!visited[nextx][nexty] && graph[nextx][nexty] === 1){ + queue.push([nextx, nexty]) + visited[nextx][nexty] = true + } + } + } + +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + // 统计岛屿数 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (!visited[i][j] && graph[i][j] === 1) { + // 遇到没访问过的陆地,+1 + result++ + + // 广度优先遍历,将相邻陆地标记为已访问 + bfs(graph, visited, i, j) + } + } + } + console.log(result); +})() +``` + + + ### TypeScript ### PhP diff --git a/problems/kamacoder/0099.岛屿的数量深搜.md b/problems/kamacoder/0099.岛屿的数量深搜.md index 37f7086a..46f7e779 100644 --- a/problems/kamacoder/0099.岛屿的数量深搜.md +++ b/problems/kamacoder/0099.岛屿的数量深搜.md @@ -191,6 +191,81 @@ int main() { ### Javascript +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph +let N, M +let visited +let result = 0 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] + +// 读取输入,初始化地图 +const initGraph = async () => { + let line = await readline(); + [N, M] = line.split(' ').map(Number); + graph = new Array(N).fill(0).map(() => new Array(M).fill(0)) + visited = new Array(N).fill(false).map(() => new Array(M).fill(false)) + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + for (let j = 0; j < M; j++) { + graph[i][j] = line[j] + } + } +} + +/** + * @description: 从节点x,y开始深度优先遍历 + * @param {*} graph 是地图,也就是一个二维数组 + * @param {*} visited 标记访问过的节点,不要重复访问 + * @param {*} x 表示开始搜索节点的下标 + * @param {*} y 表示开始搜索节点的下标 + * @return {*} + */ +const dfs = (graph, visited, x, y) => { + for (let i = 0; i < 4; i++) { + const nextx = x + dir[i][0] + const nexty = y + dir[i][1] + if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue + if (!visited[nextx][nexty] && graph[nextx][nexty] === 1) { + visited[nextx][nexty] = true + dfs(graph, visited, nextx, nexty) + } + } +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + // 统计岛屿数 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (!visited[i][j] && graph[i][j] === 1) { + // 标记已访问 + visited[i][j] = true + + // 遇到没访问过的陆地,+1 + result++ + + // 深度优先遍历,将相邻陆地标记为已访问 + dfs(graph, visited, i, j) + } + } + } + console.log(result); +})() +``` + + + ### TypeScript ### PhP From 449099e2963f1522efed65378530596e1ad422a7 Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Wed, 17 Jul 2024 14:24:30 +0800 Subject: [PATCH 10/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910100.=E5=B2=9B=E5=B1=BF=E7=9A=84=E6=9C=80=E5=A4=A7?= =?UTF-8?q?=E9=9D=A2=E7=A7=AF=20JS=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0100.岛屿的最大面积.md | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/problems/kamacoder/0100.岛屿的最大面积.md b/problems/kamacoder/0100.岛屿的最大面积.md index 19292be7..43e7e968 100644 --- a/problems/kamacoder/0100.岛屿的最大面积.md +++ b/problems/kamacoder/0100.岛屿的最大面积.md @@ -232,6 +232,96 @@ public: ### Javascript +```javascript +// 广搜版 + +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph // 地图 +let N, M // 地图大小 +let visited // 访问过的节点 +let result = 0 // 最大岛屿面积 +let count = 0 // 岛屿内节点数 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向 + + +// 读取输入,初始化地图 +const initGraph = async () => { + let line = await readline(); + [N, M] = line.split(' ').map(Number); + graph = new Array(N).fill(0).map(() => new Array(M).fill(0)) + visited = new Array(N).fill(false).map(() => new Array(M).fill(false)) + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + for (let j = 0; j < M; j++) { + graph[i][j] = line[j] + } + } +} + + +/** + * @description: 从(x, y)开始广度优先遍历 + * @param {*} graph 地图 + * @param {*} visited 访问过的节点 + * @param {*} x 开始搜索节点的下标 + * @param {*} y 开始搜索节点的下标 + * @return {*} + */ +const bfs = (graph, visited, x, y) => { + let queue = [] + queue.push([x, y]) + count++ + visited[x][y] = true //只要加入队列就立刻标记为访问过 + + while (queue.length) { + let [xx, yy] = queue.shift() + for (let i = 0; i < 4; i++) { + let nextx = xx + dir[i][0] + let nexty = yy + dir[i][1] + if(nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue + if(!visited[nextx][nexty] && graph[nextx][nexty] === 1){ + queue.push([nextx, nexty]) + count++ + visited[nextx][nexty] = true + } + } + } + +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + // 统计最大岛屿面积 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (!visited[i][j] && graph[i][j] === 1) { //遇到没有访问过的陆地 + // 重新计算面积 + count = 0 + + // 广度优先遍历,统计岛屿内节点数,并将岛屿标记为已访问 + bfs(graph, visited, i, j) + + // 更新最大岛屿面积 + result = Math.max(result, count) + } + } + } + console.log(result); +})() +``` + + + ### TypeScript ### PhP From b80f731427ca6527d2f3689933585e52a24895ee Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 17 Jul 2024 22:24:28 -0700 Subject: [PATCH 11/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200104.=E5=BB=BA?= =?UTF-8?q?=E9=80=A0=E6=9C=80=E5=A4=A7=E5=B2=9B=E5=B1=BF=20DFS=E8=A7=A3?= =?UTF-8?q?=E6=B3=95Java=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0104.建造最大岛屿.md | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/problems/kamacoder/0104.建造最大岛屿.md b/problems/kamacoder/0104.建造最大岛屿.md index b68e4442..7d67b7fc 100644 --- a/problems/kamacoder/0104.建造最大岛屿.md +++ b/problems/kamacoder/0104.建造最大岛屿.md @@ -258,6 +258,111 @@ int main() { ## 其他语言版本 ### Java +```Java +public class Main { + // 该方法采用 DFS + // 定义全局变量 + // 记录每次每个岛屿的面积 + static int count; + // 对每个岛屿进行标记 + static int mark; + // 定义二维数组表示四个方位 + static int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; + + // DFS 进行搜索,将每个岛屿标记为不同的数字 + public static void dfs(int[][] grid, int x, int y, boolean[][] visited) { + // 当遇到边界,直接return + if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length) return; + // 遇到已经访问过的或者遇到海水,直接返回 + if (visited[x][y] || grid[x][y] == 0) return; + + visited[x][y] = true; + count++; + grid[x][y] = mark; + + // 继续向下层搜索 + dfs(grid, x, y + 1, visited); + dfs(grid, x, y - 1, visited); + dfs(grid, x + 1, y, visited); + dfs(grid, x - 1, y, visited); + } + + public static void main (String[] args) { + // 接收输入 + Scanner sc = new Scanner(System.in); + int m = sc.nextInt(); + int n = sc.nextInt(); + + int[][] grid = new int[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + grid[i][j] = sc.nextInt(); + } + } + + // 初始化mark变量,从2开始(区别于0水,1岛屿) + mark = 2; + + // 定义二位boolean数组记录该位置是否被访问 + boolean[][] visited = new boolean[m][n]; + + // 定义一个HashMap,记录某片岛屿的标记号和面积 + HashMap getSize = new HashMap<>(); + + // 定义一个HashSet,用来判断某一位置水四周是否存在不同标记编号的岛屿 + HashSet set = new HashSet<>(); + + // 定义一个boolean变量,看看DFS之后,是否全是岛屿 + boolean isAllIsland = true; + + // 遍历二维数组进行DFS搜索,标记每片岛屿的编号,记录对应的面积 + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 0) isAllIsland = false; + if (grid[i][j] == 1) { + count = 0; + dfs(grid, i, j, visited); + getSize.put(mark, count); + mark++; + } + } + } + + int result = 0; + if (isAllIsland) result = m * n; + + // 对标记完的grid继续遍历,判断每个水位置四周是否有岛屿,并记录下四周不同相邻岛屿面积之和 + // 每次计算完一个水位置周围可能存在的岛屿面积之和,更新下result变量 + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 0) { + set.clear(); + // 当前水位置变更为岛屿,所以初始化为1 + int curSize = 1; + + for (int[] dir : dirs) { + int curRow = i + dir[0]; + int curCol = j + dir[1]; + + if (curRow < 0 || curRow >= m || curCol < 0 || curCol >= n) continue; + int curMark = grid[curRow][curCol]; + // 如果当前相邻的岛屿已经遍历过或者HashMap中不存在这个编号,继续搜索 + if (set.contains(curMark) || !getSize.containsKey(curMark)) continue; + set.add(curMark); + curSize += getSize.get(curMark); + } + + result = Math.max(result, curSize); + } + } + } + + // 打印结果 + System.out.println(result); + } +} + +``` ### Python From 0ed1eb394baaa66b0f7a51542fd6acf7f3880d02 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 17 Jul 2024 22:31:23 -0700 Subject: [PATCH 12/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200103.=E6=B0=B4?= =?UTF-8?q?=E6=B5=81=E9=97=AE=E9=A2=98=20DFS=E8=A7=A3=E6=B3=95Java?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0103.水流问题.md | 72 +++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/problems/kamacoder/0103.水流问题.md b/problems/kamacoder/0103.水流问题.md index 259321b6..cc6e65aa 100644 --- a/problems/kamacoder/0103.水流问题.md +++ b/problems/kamacoder/0103.水流问题.md @@ -281,6 +281,78 @@ for (int j = 0; j < m; j++) { ## 其他语言版本 ### Java +```Java +public class Main { + + // 采用 DFS 进行搜索 + public static void dfs(int[][] heights, int x, int y, boolean[][] visited, int preH) { + // 遇到边界或者访问过的点,直接返回 + if (x < 0 || x >= heights.length || y < 0 || y >= heights[0].length || visited[x][y]) return; + // 不满足水流入条件的直接返回 + if (heights[x][y] < preH) return; + // 满足条件,设置为true,表示可以从边界到达此位置 + visited[x][y] = true; + + // 向下一层继续搜索 + dfs(heights, x + 1, y, visited, heights[x][y]); + dfs(heights, x - 1, y, visited, heights[x][y]); + dfs(heights, x, y + 1, visited, heights[x][y]); + dfs(heights, x, y - 1, visited, heights[x][y]); + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int m = sc.nextInt(); + int n = sc.nextInt(); + + int[][] heights = new int[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + heights[i][j] = sc.nextInt(); + } + } + + // 初始化两个二位boolean数组,代表两个边界 + boolean[][] pacific = new boolean[m][n]; + boolean[][] atlantic = new boolean[m][n]; + + // 从左右边界出发进行DFS + for (int i = 0; i < m; i++) { + dfs(heights, i, 0, pacific, Integer.MIN_VALUE); + dfs(heights, i, n - 1, atlantic, Integer.MIN_VALUE); + } + + // 从上下边界出发进行DFS + for (int j = 0; j < n; j++) { + dfs(heights, 0, j, pacific, Integer.MIN_VALUE); + dfs(heights, m - 1, j, atlantic, Integer.MIN_VALUE); + } + + // 当两个边界二维数组在某个位置都为true时,符合题目要求 + List> res = new ArrayList<>(); + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (pacific[i][j] && atlantic[i][j]) { + res.add(Arrays.asList(i, j)); + } + } + } + + // 打印结果 + for (List list : res) { + for (int k = 0; k < list.size(); k++) { + if (k == 0) { + System.out.print(list.get(k) + " "); + } else { + System.out.print(list.get(k)); + } + } + System.out.println(); + } + } +} + +``` ### Python From ef99b46cf853a92f3104f366ac07600e7b9756b9 Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 18 Jul 2024 02:06:43 -0700 Subject: [PATCH 13/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200110.=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E6=8E=A5=E9=BE=99=20BFS=E8=A7=A3=E6=B3=95Jav?= =?UTF-8?q?a=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0110.字符串接龙.md | 62 ++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/problems/kamacoder/0110.字符串接龙.md b/problems/kamacoder/0110.字符串接龙.md index 5a60dbb7..feeec6dd 100644 --- a/problems/kamacoder/0110.字符串接龙.md +++ b/problems/kamacoder/0110.字符串接龙.md @@ -153,6 +153,68 @@ int main() { ## 其他语言版本 ### Java +```Java +public class Main { + // BFS方法 + public static int ladderLength(String beginWord, String endWord, List wordList) { + // 使用set作为查询容器,效率更高 + HashSet set = new HashSet<>(wordList); + + // 声明一个queue存储每次变更一个字符得到的且存在于容器中的新字符串 + Queue queue = new LinkedList<>(); + + // 声明一个hashMap存储遍历到的字符串以及所走过的路径path + HashMap visitMap = new HashMap<>(); + queue.offer(beginWord); + visitMap.put(beginWord, 1); + + while (!queue.isEmpty()) { + String curWord = queue.poll(); + int path = visitMap.get(curWord); + + for (int i = 0; i < curWord.length(); i++) { + char[] ch = curWord.toCharArray(); + // 每个位置尝试26个字母 + for (char k = 'a'; k <= 'z'; k++) { + ch[i] = k; + + String newWord = new String(ch); + if (newWord.equals(endWord)) return path + 1; + + // 如果这个新字符串存在于容器且之前未被访问到 + if (set.contains(newWord) && !visitMap.containsKey(newWord)) { + visitMap.put(newWord, path + 1); + queue.offer(newWord); + } + } + } + } + + return 0; + } + + public static void main (String[] args) { + /* code */ + // 接收输入 + Scanner sc = new Scanner(System.in); + int N = sc.nextInt(); + sc.nextLine(); + String[] strs = sc.nextLine().split(" "); + + List wordList = new ArrayList<>(); + for (int i = 0; i < N; i++) { + wordList.add(sc.nextLine()); + } + + // wordList.add(strs[1]); + + // 打印结果 + int result = ladderLength(strs[0], strs[1], wordList); + System.out.println(result); + } +} + +``` ### Python From 612ff79f4f2e1efe60511f52d27d510e9eb417fe Mon Sep 17 00:00:00 2001 From: kimoge <1579457263@qq.com> Date: Fri, 19 Jul 2024 10:41:04 +0800 Subject: [PATCH 14/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8D=A1=E7=A0=8199=5F?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0Python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0099.岛屿的数量广搜.md | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/problems/kamacoder/0099.岛屿的数量广搜.md b/problems/kamacoder/0099.岛屿的数量广搜.md index b9bdb796..def79bf7 100644 --- a/problems/kamacoder/0099.岛屿的数量广搜.md +++ b/problems/kamacoder/0099.岛屿的数量广搜.md @@ -192,6 +192,56 @@ int main() { ### Python +```python +from collections import deque + +# 四个方向 +position = [[0, 1], [1, 0], [0, -1], [-1, 0]] + + +def bfs(grid, visited, x, y): + """ + 广度优先搜索对陆地进行标记 + """ + + que = deque() # 创建队列 + + # 标记当前节点并加入队列 + visited[x][y] = True + que.append([x, y]) + + while que: + cur_x, cur_y = que.popleft() # 取出队首节点 + for i, j in position: + next_x = cur_x + i + next_y = cur_y + j + # 下一节点下标越界,跳过 + if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]): + continue + # 下一节点是陆地且未被访问,标记节点并加入队列 + if grid[next_x][next_y] == 1 and not visited[next_x][next_y]: + visited[next_x][next_y] = True + que.append([next_x, next_y]) + + +n, m = map(int, input().split()) +# 邻接矩阵 +grid = [] +for i in range(n): + grid.append(list(map(int, input().split()))) + +visited = [[False] * m for _ in range(n)] # 访问表 + +res = 0 +for i in range(n): + for j in range(m): + if grid[i][j] == 1 and not visited[i][j]: + res += 1 + bfs(grid, visited, i, j) + +print(res) +``` + ### Go ### Rust From cc7a9433e05d450b8f8bc732a8b15a27359bdd78 Mon Sep 17 00:00:00 2001 From: kimoge <1579457263@qq.com> Date: Fri, 19 Jul 2024 10:42:00 +0800 Subject: [PATCH 15/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8D=A1=E7=A0=81100?= =?UTF-8?q?=5F=E5=A2=9E=E5=8A=A0Python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0100.岛屿的最大面积.md | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/problems/kamacoder/0100.岛屿的最大面积.md b/problems/kamacoder/0100.岛屿的最大面积.md index 43e7e968..024e509f 100644 --- a/problems/kamacoder/0100.岛屿的最大面积.md +++ b/problems/kamacoder/0100.岛屿的最大面积.md @@ -226,6 +226,100 @@ public: ### Python +DFS + +```python +# 四个方向 +position = [[0, 1], [1, 0], [0, -1], [-1, 0]] +count = 0 + + +def dfs(grid, visited, x, y): + """ + 深度优先搜索,对一整块陆地进行标记 + """ + global count # 定义全局变量,便于传递count值 + for i, j in position: + cur_x = x + i + cur_y = y + j + # 下标越界,跳过 + if cur_x < 0 or cur_x >= len(grid) or cur_y < 0 or cur_y >= len(grid[0]): + continue + if not visited[cur_x][cur_y] and grid[cur_x][cur_y] == 1: + visited[cur_x][cur_y] = True + count += 1 + dfs(grid, visited, cur_x, cur_y) + + +n, m = map(int, input().split()) +# 邻接矩阵 +grid = [] +for i in range(n): + grid.append(list(map(int, input().split()))) +# 访问表 +visited = [[False] * m for _ in range(n)] + +result = 0 # 记录最终结果 +for i in range(n): + for j in range(m): + if grid[i][j] == 1 and not visited[i][j]: + count = 1 + visited[i][j] = True + dfs(grid, visited, i, j) + result = max(count, result) + +print(result) +``` + +BFS + +```python +from collections import deque + +position = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向 +count = 0 + + +def bfs(grid, visited, x, y): + """ + 广度优先搜索对陆地进行标记 + """ + global count # 声明全局变量 + que = deque() + que.append([x, y]) + while que: + cur_x, cur_y = que.popleft() + for i, j in position: + next_x = cur_x + i + next_y = cur_y + j + # 下标越界,跳过 + if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]): + continue + if grid[next_x][next_y] == 1 and not visited[next_x][next_y]: + visited[next_x][next_y] = True + count += 1 + que.append([next_x, next_y]) + + +n, m = map(int, input().split()) +# 邻接矩阵 +grid = [] +for i in range(n): + grid.append(list(map(int, input().split()))) +visited = [[False] * m for _ in range(n)] # 访问表 + +result = 0 # 记录最终结果 +for i in range(n): + for j in range(m): + if grid[i][j] == 1 and not visited[i][j]: + count = 1 + visited[i][j] = True + bfs(grid, visited, i, j) + res = max(result, count) + +print(result) +``` + ### Go ### Rust From 530f512211b155cc1643f3c0bdf2d05ee4bd1c0c Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Fri, 19 Jul 2024 14:18:14 +0800 Subject: [PATCH 16/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910101.=E5=AD=A4=E5=B2=9B=E7=9A=84=E6=80=BB=E9=9D=A2?= =?UTF-8?q?=E7=A7=AF=20JS=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0101.孤岛的总面积.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/problems/kamacoder/0101.孤岛的总面积.md b/problems/kamacoder/0101.孤岛的总面积.md index 25de67ec..a1793337 100644 --- a/problems/kamacoder/0101.孤岛的总面积.md +++ b/problems/kamacoder/0101.孤岛的总面积.md @@ -242,6 +242,173 @@ print(count) ### Javascript +#### 深搜版 + +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph // 地图 +let N, M // 地图大小 +let count = 0 // 孤岛的总面积 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向 + + +// 读取输入,初始化地图 +const initGraph = async () => { + let line = await readline(); + [N, M] = line.split(' ').map(Number); + graph = new Array(N).fill(0).map(() => new Array(M).fill(0)) + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + for (let j = 0; j < M; j++) { + graph[i][j] = line[j] + } + } +} + + +/** + * @description: 从(x,y)开始深度优先遍历地图 + * @param {*} graph 地图 + * @param {*} x 开始搜索节点的下标 + * @param {*} y 开始搜索节点的下标 + * @return {*} + */ +const dfs = (graph, x, y) => { + if(graph[x][y] === 0) return + graph[x][y] = 0 // 标记为海洋 + for (let i = 0; i < 4; i++) { + let nextx = x + dir[i][0] + let nexty = y + dir[i][1] + if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue + dfs(graph, nextx, nexty) + } +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + // 遍历地图左右两边 + for (let i = 0; i < N; i++) { + if (graph[i][0] === 1) dfs(graph, i, 0) + if (graph[i][M - 1] === 1) dfs(graph, i, M - 1) + } + + // 遍历地图上下两边 + for (let j = 0; j < M; j++) { + if (graph[0][j] === 1) dfs(graph, 0, j) + if (graph[N - 1][j] === 1) dfs(graph, N - 1, j) + } + + count = 0 + // 统计孤岛的总面积 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (graph[i][j] === 1) count++ + } + } + console.log(count); +})() +``` + + + +#### 广搜版 + +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph // 地图 +let N, M // 地图大小 +let count = 0 // 孤岛的总面积 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向 + + +// 读取输入,初始化地图 +const initGraph = async () => { + let line = await readline(); + [N, M] = line.split(' ').map(Number); + graph = new Array(N).fill(0).map(() => new Array(M).fill(0)) + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + for (let j = 0; j < M; j++) { + graph[i][j] = line[j] + } + } +} + + +/** + * @description: 从(x,y)开始广度优先遍历地图 + * @param {*} graph 地图 + * @param {*} x 开始搜索节点的下标 + * @param {*} y 开始搜索节点的下标 + * @return {*} + */ +const bfs = (graph, x, y) => { + let queue = [] + queue.push([x, y]) + graph[x][y] = 0 // 只要加入队列,立刻标记 + + while (queue.length) { + let [xx, yy] = queue.shift() + for (let i = 0; i < 4; i++) { + let nextx = xx + dir[i][0] + let nexty = yy + dir[i][1] + if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue + if (graph[nextx][nexty] === 1) { + queue.push([nextx, nexty]) + graph[nextx][nexty] = 0 // 只要加入队列,立刻标记 + } + } + } + +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + // 遍历地图左右两边 + for (let i = 0; i < N; i++) { + if (graph[i][0] === 1) bfs(graph, i, 0) + if (graph[i][M - 1] === 1) bfs(graph, i, M - 1) + } + + // 遍历地图上下两边 + for (let j = 0; j < M; j++) { + if (graph[0][j] === 1) bfs(graph, 0, j) + if (graph[N - 1][j] === 1) bfs(graph, N - 1, j) + } + + count = 0 + // 统计孤岛的总面积 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (graph[i][j] === 1) count++ + } + } + console.log(count); +})() +``` + + + ### TypeScript ### PhP From 3dce79d5873c71ddeadf2e9304a20272ff11987d Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Fri, 19 Jul 2024 14:22:29 +0800 Subject: [PATCH 17/22] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910102.=E6=B2=89=E6=B2=A1=E5=AD=A4=E5=B2=9B=20JS?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0102.沉没孤岛.md | 165 ++++++++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/problems/kamacoder/0102.沉没孤岛.md b/problems/kamacoder/0102.沉没孤岛.md index 5491a8e3..2b16da04 100644 --- a/problems/kamacoder/0102.沉没孤岛.md +++ b/problems/kamacoder/0102.沉没孤岛.md @@ -146,6 +146,171 @@ int main() { ### Javascript +#### 深搜版 + +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph // 地图 +let N, M // 地图大小 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向 + + +// 读取输入,初始化地图 +const initGraph = async () => { + let line = await readline(); + [N, M] = line.split(' ').map(Number); + graph = new Array(N).fill(0).map(() => new Array(M).fill(0)) + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + for (let j = 0; j < M; j++) { + graph[i][j] = line[j] + } + } +} + + +/** + * @description: 从(x,y)开始深度优先遍历地图 + * @param {*} graph 地图 + * @param {*} x 开始搜索节点的下标 + * @param {*} y 开始搜索节点的下标 + * @return {*} + */ +const dfs = (graph, x, y) => { + if (graph[x][y] !== 1) return + graph[x][y] = 2 // 标记为非孤岛陆地 + + for (let i = 0; i < 4; i++) { + let nextx = x + dir[i][0] + let nexty = y + dir[i][1] + if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue + dfs(graph, nextx, nexty) + } +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + // 遍历地图左右两边 + for (let i = 0; i < N; i++) { + if (graph[i][0] === 1) dfs(graph, i, 0) + if (graph[i][M - 1] === 1) dfs(graph, i, M - 1) + } + + // 遍历地图上下两边 + for (let j = 0; j < M; j++) { + if (graph[0][j] === 1) dfs(graph, 0, j) + if (graph[N - 1][j] === 1) dfs(graph, N - 1, j) + } + + + // 遍历地图,将孤岛沉没,即将陆地1标记为0;将非孤岛陆地2标记为1 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (graph[i][j] === 1) graph[i][j] = 0 + else if (graph[i][j] === 2) graph[i][j] = 1 + } + console.log(graph[i].join(' ')); + } +})() +``` + + + +#### 广搜版 + +```javascript +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + +let graph // 地图 +let N, M // 地图大小 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向 + + +// 读取输入,初始化地图 +const initGraph = async () => { + let line = await readline(); + [N, M] = line.split(' ').map(Number); + graph = new Array(N).fill(0).map(() => new Array(M).fill(0)) + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + for (let j = 0; j < M; j++) { + graph[i][j] = line[j] + } + } +} + + +/** + * @description: 从(x,y)开始广度优先遍历地图 + * @param {*} graph 地图 + * @param {*} x 开始搜索节点的下标 + * @param {*} y 开始搜索节点的下标 + * @return {*} + */ +const bfs = (graph, x, y) => { + let queue = [] + queue.push([x, y]) + graph[x][y] = 2 // 标记为非孤岛陆地 + + while (queue.length) { + let [xx, yy] = queue.shift() + + for (let i = 0; i < 4; i++) { + let nextx = xx + dir[i][0] + let nexty = yy + dir[i][1] + if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue + if (graph[nextx][nexty] === 1) bfs(graph, nextx, nexty) + } + } +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + // 遍历地图左右两边 + for (let i = 0; i < N; i++) { + if (graph[i][0] === 1) bfs(graph, i, 0) + if (graph[i][M - 1] === 1) bfs(graph, i, M - 1) + } + + // 遍历地图上下两边 + for (let j = 0; j < M; j++) { + if (graph[0][j] === 1) bfs(graph, 0, j) + if (graph[N - 1][j] === 1) bfs(graph, N - 1, j) + } + + + // 遍历地图,将孤岛沉没,即将陆地1标记为0;将非孤岛陆地2标记为1 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (graph[i][j] === 1) graph[i][j] = 0 + else if (graph[i][j] === 2) graph[i][j] = 1 + } + console.log(graph[i].join(' ')); + } +})() +``` + + + ### TypeScript ### PhP From 8d29bef3f7b5ce7064a0d0ca041f99914cb2ccf2 Mon Sep 17 00:00:00 2001 From: Charlie Yang <104724079+sxdtywm@users.noreply.github.com> Date: Sun, 21 Jul 2024 22:01:29 +0800 Subject: [PATCH 18/22] feat:add algorithm of go python js java etc. feat:add algorithm of go python js java etc. --- .../kamacoder/0099.岛屿的数量广搜.md | 204 ++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/problems/kamacoder/0099.岛屿的数量广搜.md b/problems/kamacoder/0099.岛屿的数量广搜.md index b9bdb796..3c069b44 100644 --- a/problems/kamacoder/0099.岛屿的数量广搜.md +++ b/problems/kamacoder/0099.岛屿的数量广搜.md @@ -190,10 +190,164 @@ int main() { ### Java +```java + +import java.util.Scanner; + +public class Main { + static int[][] dir = { {0, 1}, {1, 0}, {-1, 0}, {0, -1} }; // 四个方向 + + public static void dfs(int[][] grid, boolean[][] visited, int x, int y) { + for (int i = 0; i < 4; i++) { + int nextx = x + dir[i][0]; + int nexty = y + dir[i][1]; + if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue; // 越界了,直接跳过 + if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) { // 没有访问过的 同时 是陆地的 + visited[nextx][nexty] = true; + dfs(grid, visited, nextx, nexty); + } + } + } + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + int n = scanner.nextInt(); + int m = scanner.nextInt(); + int[][] grid = new int[n][m]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + grid[i][j] = scanner.nextInt(); + } + } + + boolean[][] visited = new boolean[n][m]; + + int result = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (!visited[i][j] && grid[i][j] == 1) { + visited[i][j] = true; + result++; // 遇到没访问过的陆地,+1 + dfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true + } + } + } + + System.out.println(result); + } +} + + + +``` + + ### Python +```python + +def dfs(grid, visited, x, y): + dir = [(0, 1), (1, 0), (-1, 0), (0, -1)] # 四个方向 + for d in dir: + nextx, nexty = x + d[0], y + d[1] + if 0 <= nextx < len(grid) and 0 <= nexty < len(grid[0]): + if not visited[nextx][nexty] and grid[nextx][nexty] == 1: # 没有访问过的 同时 是陆地的 + visited[nextx][nexty] = True + dfs(grid, visited, nextx, nexty) + +def main(): + n, m = map(int, input().split()) + grid = [list(map(int, input().split())) for _ in range(n)] + visited = [[False] * m for _ in range(n)] + + result = 0 + for i in range(n): + for j in range(m): + if not visited[i][j] and grid[i][j] == 1: + visited[i][j] = True + result += 1 # 遇到没访问过的陆地,+1 + dfs(grid, visited, i, j) # 将与其链接的陆地都标记上 True + + print(result) + +if __name__ == "__main__": + main() + + + +``` + + ### Go +```go + +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +var dir = [4][2]int{{0, 1}, {1, 0}, {-1, 0}, {0, -1}} // 四个方向 + +func dfs(grid [][]int, visited [][]bool, x, y int) { + for i := 0; i < 4; i++ { + nextx := x + dir[i][0] + nexty := y + dir[i][1] + if nextx < 0 || nextx >= len(grid) || nexty < 0 || nexty >= len(grid[0]) { + continue // 越界了,直接跳过 + } + if !visited[nextx][nexty] && grid[nextx][nexty] == 1 { // 没有访问过的 同时 是陆地的 + visited[nextx][nexty] = true + dfs(grid, visited, nextx, nexty) + } + } +} + +func main() { + reader := bufio.NewReader(os.Stdin) + var n, m int + fmt.Scanf("%d %d", &n, &m) + + grid := make([][]int, n) + for i := 0; i < n; i++ { + grid[i] = make([]int, m) + line, _ := reader.ReadString('\n') + line = strings.TrimSpace(line) + elements := strings.Split(line, " ") + for j := 0; j < m; j++ { + grid[i][j], _ = strconv.Atoi(elements[j]) + } + } + + visited := make([][]bool, n) + for i := 0; i < n; i++ { + visited[i] = make([]bool, m) + } + + result := 0 + for i := 0; i < n; i++ { + for j := 0; j < m; j++ { + if !visited[i][j] && grid[i][j] == 1 { + visited[i][j] = true + result++ // 遇到没访问过的陆地,+1 + dfs(grid, visited, i, j) // 将与其链接的陆地都标记上 true + } + } + } + + fmt.Println(result) +} + + +``` + + + ### Rust ### Javascript @@ -283,12 +437,62 @@ const bfs = (graph, visited, x, y) => { ### PhP +```PHP + += count($grid) || $nexty < 0 || $nexty >= count($grid[0])) { + continue; // 越界了,直接跳过 + } + if (!$visited[$nextx][$nexty] && $grid[$nextx][$nexty] == 1) { // 没有访问过的 同时 是陆地的 + $visited[$nextx][$nexty] = true; + dfs($grid, $visited, $nextx, $nexty); + } + } +} + +function main() { + fscanf(STDIN, "%d %d", $n, $m); + $grid = []; + for ($i = 0; $i < $n; $i++) { + $grid[$i] = array_map('intval', explode(' ', trim(fgets(STDIN)))); + } + + $visited = array_fill(0, $n, array_fill(0, $m, false)); + + $result = 0; + for ($i = 0; $i < $n; $i++) { + for ($j = 0; $j < $m; $j++) { + if (!$visited[$i][$j] && $grid[$i][$j] == 1) { + $visited[$i][$j] = true; + $result++; // 遇到没访问过的陆地,+1 + dfs($grid, $visited, $i, $j); // 将与其链接的陆地都标记上 true + } + } + } + + echo $result . PHP_EOL; +} + +main(); +?> + + +``` + + ### Swift ### Scala ### C# + ### Dart ### C From 9eb819e3be9d75b2311837911594ee646e17954d Mon Sep 17 00:00:00 2001 From: Allen Guo Date: Sun, 21 Jul 2024 15:34:30 -0700 Subject: [PATCH 19/22] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200106.=E5=B2=9B?= =?UTF-8?q?=E5=B1=BF=E7=9A=84=E5=91=A8=E9=95=BF=20Java=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0106.岛屿的周长.md | 57 +++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/problems/kamacoder/0106.岛屿的周长.md b/problems/kamacoder/0106.岛屿的周长.md index 48400a95..6f3462c5 100644 --- a/problems/kamacoder/0106.岛屿的周长.md +++ b/problems/kamacoder/0106.岛屿的周长.md @@ -157,7 +157,62 @@ int main() { ## 其他语言版本 -### Java +### Java +```Java +import java.util.*; + +public class Main { + // 每次遍历到1,探索其周围4个方向,并记录周长,最终合计 + // 声明全局变量,dirs表示4个方向 + static int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; + // 统计每单个1的周长 + static int count; + + // 探索其周围4个方向,并记录周长 + public static void helper(int[][] grid, int x, int y) { + for (int[] dir : dirs) { + int nx = x + dir[0]; + int ny = y + dir[1]; + + // 遇到边界或者水,周长加一 + if (nx < 0 || nx >= grid.length || ny < 0 || ny >= grid[0].length + || grid[nx][ny] == 0) { + count++; + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 接收输入 + int M = sc.nextInt(); + int N = sc.nextInt(); + + int[][] grid = new int[M][N]; + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) { + grid[i][j] = sc.nextInt(); + } + } + + int result = 0; // 总周长 + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) { + if (grid[i][j] == 1) { + count = 0; + helper(grid, i, j); + // 更新总周长 + result += count; + } + } + } + + // 打印结果 + System.out.println(result); + } +} +``` ### Python From c7efbc1949688b59d20e626e138507aebca6e482 Mon Sep 17 00:00:00 2001 From: muzi-xiaoren <106290465+muzi-xiaoren@users.noreply.github.com> Date: Mon, 22 Jul 2024 18:21:29 +0800 Subject: [PATCH 20/22] =?UTF-8?q?Update=200349.=E4=B8=A4=E4=B8=AA=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E7=9A=84=E4=BA=A4=E9=9B=86.md--Ruby=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0349.两个数组的交集.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index e17e940f..77dfc50a 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -511,7 +511,7 @@ object Solution { ``` -###Ruby +### Ruby: ```ruby def intersection(nums1, nums2) hash = {} From 1c2ac1587f86433b29ffb9618a35ebf9bd9eece3 Mon Sep 17 00:00:00 2001 From: robotsouper Date: Mon, 22 Jul 2024 08:51:23 -0400 Subject: [PATCH 21/22] =?UTF-8?q?Leetcode=20131(Java):=20=E7=9B=B8?= =?UTF-8?q?=E5=90=8C=E7=9A=84=E6=80=9D=E8=B7=AF=E4=BD=86=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E8=AE=A4=E4=B8=BA=E6=9B=B4=E5=A5=BD=E7=90=86=E8=A7=A3=E7=9A=84?= =?UTF-8?q?=E5=86=99=E6=B3=95=EF=BC=8C=E9=81=B5=E5=BE=AA=E5=89=8D=E4=B8=A4?= =?UTF-8?q?=E9=A2=98=EF=BC=88combination=20sum=EF=BC=89=E7=9A=84=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E4=BB=8E=E8=80=8C=E6=9B=B4=E5=8A=A0=E6=98=93=E6=87=82?= =?UTF-8?q?=EF=BC=8C=E5=AF=B9=E4=BA=8Ecur=E7=9A=84=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=94=BE=E5=BC=83deque=EF=BC=8C=E4=BF=9D=E6=8C=81=E4=BC=A0?= =?UTF-8?q?=E7=BB=9F=E4=BB=8D=E7=84=B6=E4=BD=BF=E7=94=A8arraylist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0131.分割回文串.md | 48 +++++++++++++++----------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index 822d4399..4a868651 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -310,39 +310,35 @@ public: ### Java ```Java class Solution { - List> lists = new ArrayList<>(); - Deque deque = new LinkedList<>(); - + //保持前几题一贯的格式, initialization + List> res = new ArrayList<>(); + List cur = new ArrayList<>(); public List> partition(String s) { - backTracking(s, 0); - return lists; + backtracking(s, 0, new StringBuilder()); + return res; } - - private void backTracking(String s, int startIndex) { - //如果起始位置大于s的大小,说明找到了一组分割方案 - if (startIndex >= s.length()) { - lists.add(new ArrayList(deque)); + private void backtracking(String s, int start, StringBuilder sb){ + //因为是起始位置一个一个加的,所以结束时start一定等于s.length,因为进入backtracking时一定末尾也是回文,所以cur是满足条件的 + if (start == s.length()){ + //注意创建一个新的copy + res.add(new ArrayList<>(cur)); return; } - for (int i = startIndex; i < s.length(); i++) { - //如果是回文子串,则记录 - if (isPalindrome(s, startIndex, i)) { - String str = s.substring(startIndex, i + 1); - deque.addLast(str); - } else { - continue; + //像前两题一样从前往后搜索,如果发现回文,进入backtracking,起始位置后移一位,循环结束照例移除cur的末位 + for (int i = start; i < s.length(); i++){ + sb.append(s.charAt(i)); + if (check(sb)){ + cur.add(sb.toString()); + backtracking(s, i + 1, new StringBuilder()); + cur.remove(cur.size() -1 ); } - //起始位置后移,保证不重复 - backTracking(s, i + 1); - deque.removeLast(); } } - //判断是否是回文串 - private boolean isPalindrome(String s, int startIndex, int end) { - for (int i = startIndex, j = end; i < j; i++, j--) { - if (s.charAt(i) != s.charAt(j)) { - return false; - } + + //helper method, 检查是否是回文 + private boolean check(StringBuilder sb){ + for (int i = 0; i < sb.length()/ 2; i++){ + if (sb.charAt(i) != sb.charAt(sb.length() - 1 - i)){return false;} } return true; } From 22a6522a37ed279ac9749ca394f7c9c1835c1c57 Mon Sep 17 00:00:00 2001 From: Relsola Date: Wed, 24 Jul 2024 00:05:41 +0800 Subject: [PATCH 22/22] =?UTF-8?q?Update=20707.=E8=AE=BE=E8=AE=A1=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=20=20=E4=BC=98=E5=8C=96=20C=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E5=92=8C=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0707.设计链表.md | 135 ++++++++++++++++------------------ 1 file changed, 65 insertions(+), 70 deletions(-) diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index 743c1d7f..141156cf 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -168,109 +168,103 @@ private: ### C: ```C -typedef struct MyLinkedList { - int val; - struct MyLinkedList* next; -}MyLinkedList; +typedef struct Node { + int val; + struct Node* next; +} Node; + + +typedef struct { + int size; + Node* data; +} MyLinkedList; /** Initialize your data structure here. */ MyLinkedList* myLinkedListCreate() { - //这个题必须用虚拟头指针,参数都是一级指针,头节点确定后没法改指向了!!! - MyLinkedList* head = (MyLinkedList *)malloc(sizeof (MyLinkedList)); - head->next = NULL; - return head; + MyLinkedList* obj = (MyLinkedList*)malloc(sizeof(MyLinkedList)); + Node* head = (Node*)malloc(sizeof(Node)); + head->next = (void*)0; + obj->data = head; + obj->size = 0; + return obj; } /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ int myLinkedListGet(MyLinkedList* obj, int index) { - MyLinkedList *cur = obj->next; - for (int i = 0; cur != NULL; i++){ - if (i == index){ - return cur->val; - } - else{ - cur = cur->next; - } + if (index < 0 || index >= obj->size) return -1; + + Node* cur = obj->data; + while (index-- >= 0) { + cur = cur->next; } - return -1; + + return cur->val; } /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ void myLinkedListAddAtHead(MyLinkedList* obj, int val) { - MyLinkedList *nhead = (MyLinkedList *)malloc(sizeof (MyLinkedList)); - nhead->val = val; - nhead->next = obj->next; - obj->next = nhead; + Node* node = (Node*)malloc(sizeof(Node)); + node->val = val; + node->next = obj->data->next; + obj->data->next = node; + obj->size++; } /** Append a node of value val to the last element of the linked list. */ void myLinkedListAddAtTail(MyLinkedList* obj, int val) { - MyLinkedList *cur = obj; - while(cur->next != NULL){ + Node* cur = obj->data; + while (cur->next != ((void*)0)) { cur = cur->next; } - MyLinkedList *ntail = (MyLinkedList *)malloc(sizeof (MyLinkedList)); - ntail->val = val; - ntail->next = NULL; - cur->next = ntail; + + Node* tail = (Node*)malloc(sizeof(Node)); + tail->val = val; + tail->next = (void*)0; + cur->next = tail; + obj->size++; } /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) { - if (index == 0){ - myLinkedListAddAtHead(obj, val); - return; - } - MyLinkedList *cur = obj->next; - for (int i = 1 ;cur != NULL; i++){ - if (i == index){ - MyLinkedList* newnode = (MyLinkedList *)malloc(sizeof (MyLinkedList)); - newnode->val = val; - newnode->next = cur->next; - cur->next = newnode; - return; - } - else{ - cur = cur->next; - } + if (index > obj->size) return; + + Node* cur = obj->data; + while (index-- > 0) { + cur = cur->next; } + + Node* node = (Node*)malloc(sizeof(Node)); + node->val = val; + node->next = cur->next; + cur->next = node; + obj->size++; } /** Delete the index-th node in the linked list, if the index is valid. */ void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) { - if (index == 0){ - MyLinkedList *tmp = obj->next; - if (tmp != NULL){ - obj->next = tmp->next; - free(tmp); - } - return; + if (index < 0 || index >= obj->size) return; + + Node* cur = obj->data; + while (index-- > 0) { + cur = cur->next; } - MyLinkedList *cur = obj->next; - for (int i = 1 ;cur != NULL && cur->next != NULL; i++){ - if (i == index){ - MyLinkedList *tmp = cur->next; - if (tmp != NULL) { - cur->next = tmp->next; - free(tmp); - } - return; - } - else{ - cur = cur->next; - } - } - + + Node* temp = cur->next; + cur->next = temp->next; + free(temp); + obj->size--; } void myLinkedListFree(MyLinkedList* obj) { - while(obj != NULL){ - MyLinkedList *tmp = obj; - obj = obj->next; - free(tmp); - } + Node* tmp = obj->data; + while (tmp != NULL) { + Node* n = tmp; + tmp = tmp->next; + free(n); + } + free(obj); } /** @@ -1569,3 +1563,4 @@ public class MyLinkedList +