From 1c9f885fa52047f942bd8627c0ffd835e5a8c629 Mon Sep 17 00:00:00 2001 From: markwang Date: Thu, 25 Jul 2024 14:50:10 +0800 Subject: [PATCH 01/27] =?UTF-8?q?90.=E5=AD=90=E9=9B=86II=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?Go=E4=BD=BF=E7=94=A8used=E6=95=B0=E7=BB=84=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0090.子集II.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/problems/0090.子集II.md b/problems/0090.子集II.md index 03bbd1dc..939ef369 100644 --- a/problems/0090.子集II.md +++ b/problems/0090.子集II.md @@ -310,6 +310,43 @@ class Solution: ``` ### Go +使用used数组 +```Go +var ( + result [][]int + path []int +) + +func subsetsWithDup(nums []int) [][]int { + result = make([][]int, 0) + path = make([]int, 0) + used := make([]bool, len(nums)) + sort.Ints(nums) // 去重需要排序 + backtracing(nums, 0, used) + return result +} + +func backtracing(nums []int, startIndex int, used []bool) { + tmp := make([]int, len(path)) + copy(tmp, path) + result = append(result, tmp) + for i := startIndex; i < len(nums); i++ { + // used[i - 1] == true,说明同一树枝candidates[i - 1]使用过 + // used[i - 1] == false,说明同一树层candidates[i - 1]使用过 + // 而我们要对同一树层使用过的元素进行跳过 + if i > 0 && nums[i] == nums[i-1] && used[i-1] == false { + continue + } + path = append(path, nums[i]) + used[i] = true + backtracing(nums, i + 1, used) + path = path[:len(path)-1] + used[i] = false + } +} +``` + +不使用used数组 ```Go var ( path []int From c3541789614a1703154125f3e7a26592f5f2bc5e Mon Sep 17 00:00:00 2001 From: Lifan Sun Date: Thu, 25 Jul 2024 16:11:38 +0800 Subject: [PATCH 02/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200203.=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E9=93=BE=E8=A1=A8=E5=85=83=E7=B4=A0=E9=80=92=E5=BD=92?= =?UTF-8?q?=E8=A7=A3=E6=B3=95=20C++=20=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0203.移除链表元素.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index 64124fbb..f6b5ef6d 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -149,7 +149,35 @@ public: * 时间复杂度: O(n) * 空间复杂度: O(1) +**也可以通过递归的思路解决本题:** +基础情况:对于空链表,不需要移除元素。 + +递归情况:首先检查头节点的值是否为 val,如果是则移除头节点,答案即为在头节点的后续节点上递归的结果;如果头节点的值不为 val,则答案为头节点与在头节点的后续节点上递归得到的新链表拼接的结果。 + +```CPP +class Solution { +public: + ListNode* removeElements(ListNode* head, int val) { + // 基础情况:空链表 + if (head == nullptr) { + return nullptr; + } + + // 递归处理 + if (head->val == val) { + ListNode* newHead = removeElements(head->next, val); + delete head; + return newHead; + } else { + head->next = removeElements(head->next, val); + return head; + } + } +}; +``` +* 时间复杂度:O(n) +* 空间复杂度:O(n) ## 其他语言版本 From 5fc9aa68a3f483b41ddae1fe735cfe21a676d7dd Mon Sep 17 00:00:00 2001 From: Hard <2321291138@qq.com> Date: Mon, 5 Aug 2024 17:24:26 +0800 Subject: [PATCH 03/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A00116.=E5=A1=AB=E5=85=85?= =?UTF-8?q?=E6=AF=8F=E4=B8=AA=E8=8A=82=E7=82=B9=E7=9A=84=E4=B8=8B=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E5=8F=B3=E4=BE=A7=E8=8A=82=E7=82=B9=E6=8C=87=E9=92=88?= =?UTF-8?q?.md=20Java=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...个节点的下一个右侧节点指针.md | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/problems/0116.填充每个节点的下一个右侧节点指针.md b/problems/0116.填充每个节点的下一个右侧节点指针.md index ca36ac6f..98bd4e41 100644 --- a/problems/0116.填充每个节点的下一个右侧节点指针.md +++ b/problems/0116.填充每个节点的下一个右侧节点指针.md @@ -169,6 +169,56 @@ class Solution { } ``` +```Java +// 迭代法 +class Solution { + public Node connect(Node root) { + if (root == null) { + return root; + } + + Queue queue = new LinkedList<>(); + + queue.add(root); + + while (!queue.isEmpty()) { + int size = queue.size(); + + // 每层的第一个节点 + Node cur = queue.poll(); + if (cur.left != null) { + queue.add(cur.left); + } + if (cur.right != null) { + queue.add(cur.right); + } + + // 因为已经移除了每层的第一个节点,所以将 0 改为 1 + while (size-- > 1) { + Node next = queue.poll(); + + if (next.left != null) { + queue.add(next.left); + } + if (next.right != null) { + queue.add(next.right); + } + + // 当前节点指向同层的下一个节点 + cur.next = next; + // 更新当前节点 + cur = next; + } + + // 每层的最后一个节点不指向 null 在力扣也能过 + cur.next = null; + } + + return root; + } +} +``` + ### Python ```python @@ -443,3 +493,4 @@ public class Solution + From a91e01c8a4479f9a2871d895ccc5c0af283d8a9c Mon Sep 17 00:00:00 2001 From: Hard <2321291138@qq.com> Date: Mon, 5 Aug 2024 17:25:35 +0800 Subject: [PATCH 04/27] =?UTF-8?q?=E4=BF=AE=E6=94=B90226.=E7=BF=BB=E8=BD=AC?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91.md=20=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0226.翻转二叉树.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/problems/0226.翻转二叉树.md b/problems/0226.翻转二叉树.md index 824968f0..e501b298 100644 --- a/problems/0226.翻转二叉树.md +++ b/problems/0226.翻转二叉树.md @@ -14,7 +14,7 @@ ![226.翻转二叉树](https://code-thinking-1253855093.file.myqcloud.com/pics/20210203192644329.png) -这道题目背后有一个让程序员心酸的故事,听说 Homebrew的作者Max Howell,就是因为没在白板上写出翻转二叉树,最后被Google拒绝了。(真假不做判断,权当一个乐子哈) +这道题目背后有一个让程序员心酸的故事,听说 Homebrew的作者Max Howell,就是因为没在白板上写出翻转二叉树,最后被Google拒绝了。(真假不做判断,全当一个乐子哈) ## 算法公开课 @@ -1033,3 +1033,4 @@ public TreeNode InvertTree(TreeNode root) { + From 2272d0e1e303f93d6a61e33674c799d848817824 Mon Sep 17 00:00:00 2001 From: Yang-Changhui <2275029710@qq.com> Date: Mon, 5 Aug 2024 23:05:41 +0800 Subject: [PATCH 05/27] =?UTF-8?q?add=20problems/kamacoder/0110.=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=E6=8E=A5=E9=BE=99.md=20python?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0110.字符串接龙.md | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/problems/kamacoder/0110.字符串接龙.md b/problems/kamacoder/0110.字符串接龙.md index feeec6dd..5d13e368 100644 --- a/problems/kamacoder/0110.字符串接龙.md +++ b/problems/kamacoder/0110.字符串接龙.md @@ -217,6 +217,38 @@ public class Main { ``` ### Python +```Python +def judge(s1,s2): + count=0 + for i in range(len(s1)): + if s1[i]!=s2[i]: + count+=1 + return count==1 + +if __name__=='__main__': + n=int(input()) + beginstr,endstr=map(str,input().split()) + if beginstr==endstr: + print(0) + exit() + strlist=[] + for i in range(n): + strlist.append(input()) + + # use bfs + visit=[False for i in range(n)] + queue=[[beginstr,1]] + while queue: + str,step=queue.pop(0) + if judge(str,endstr): + print(step+1) + exit() + for i in range(n): + if visit[i]==False and judge(strlist[i],str): + visit[i]=True + queue.append([strlist[i],step+1]) + print(0) +``` ### Go From a13de64145b21f31b42e6162623b25fe7103f863 Mon Sep 17 00:00:00 2001 From: kyshen Date: Mon, 5 Aug 2024 23:21:33 +0800 Subject: [PATCH 06/27] feat: 0104 python DFS solution --- problems/kamacoder/0104.建造最大岛屿.md | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/problems/kamacoder/0104.建造最大岛屿.md b/problems/kamacoder/0104.建造最大岛屿.md index 7d67b7fc..7132217b 100644 --- a/problems/kamacoder/0104.建造最大岛屿.md +++ b/problems/kamacoder/0104.建造最大岛屿.md @@ -366,6 +366,79 @@ public class Main { ### Python +```Python +import collections + +directions = [[-1, 0], [0, 1], [0, -1], [1, 0]] +area = 0 + +def dfs(i, j, grid, visited, num): + global area + + if visited[i][j]: + return + + visited[i][j] = True + grid[i][j] = num # 标记岛屿号码 + area += 1 + + for x, y in directions: + new_x = i + x + new_y = j + y + if ( + 0 <= new_x < len(grid) + and 0 <= new_y < len(grid[0]) + and grid[new_x][new_y] == "1" + ): + dfs(new_x, new_y, grid, visited, num) + + +def main(): + global area + + N, M = map(int, input().strip().split()) + grid = [] + for i in range(N): + grid.append(input().strip().split()) + visited = [[False] * M for _ in range(N)] + rec = collections.defaultdict(int) + + cnt = 2 + for i in range(N): + for j in range(M): + if grid[i][j] == "1": + area = 0 + dfs(i, j, grid, visited, cnt) + rec[cnt] = area # 纪录岛屿面积 + cnt += 1 + + res = 0 + for i in range(N): + for j in range(M): + if grid[i][j] == "0": + max_island = 1 # 将水变为陆地,故从1开始计数 + v = set() + for x, y in directions: + new_x = i + x + new_y = j + y + if ( + 0 <= new_x < len(grid) + and 0 <= new_y < len(grid[0]) + and grid[new_x][new_y] != "0" + and grid[new_x][new_y] not in v # 岛屿不可重复 + ): + max_island += rec[grid[new_x][new_y]] + v.add(grid[new_x][new_y]) + res = max(res, max_island) + + if res == 0: + return max(rec.values()) # 无水的情况 + return res + +if __name__ == "__main__": + print(main()) +``` + ### Go ### Rust From d38135b219e667f1638b9184b015043a87ed002a Mon Sep 17 00:00:00 2001 From: fang_chenfang <1217690899@qq.com> Date: Tue, 6 Aug 2024 10:36:18 +0800 Subject: [PATCH 07/27] =?UTF-8?q?Update=200018.=E5=9B=9B=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Java版本第二个for循环内的剪枝操作直接return会漏解,应该是break --- problems/0018.四数之和.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index 8e34713d..f45dd939 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -264,7 +264,7 @@ class Solution { // nums[i]+nums[j] > target 直接返回, 剪枝操作 if (nums[i]+nums[j] > 0 && nums[i]+nums[j] > target) { - return result; + break; } if (j > i + 1 && nums[j - 1] == nums[j]) { // 对nums[j]去重 From 0cdfc3fef87a285f3ddc0e9ddce491c1f38a69de Mon Sep 17 00:00:00 2001 From: ma <501847822@qq.com> Date: Wed, 7 Aug 2024 10:46:56 +0800 Subject: [PATCH 08/27] =?UTF-8?q?Update=200018.=E5=9B=9B=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C.md=20=E6=9B=B4=E6=96=B0=20Java=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0018.四数之和.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index 8e34713d..961de9ba 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -251,8 +251,8 @@ class Solution { for (int i = 0; i < nums.length; i++) { - // nums[i] > target 直接返回, 剪枝操作 - if (nums[i] > 0 && nums[i] > target) { + // nums[i] >= 0 && nums[i] > target 直接返回, 剪枝操作 + if (nums[i] >= 0 && nums[i] > target) { return result; } @@ -262,10 +262,10 @@ class Solution { for (int j = i + 1; j < nums.length; j++) { - // nums[i]+nums[j] > target 直接返回, 剪枝操作 - if (nums[i]+nums[j] > 0 && nums[i]+nums[j] > target) { - return result; - } + // nums[i] >= 0 && nums[i] + nums[j] > target 剪枝操作 + if (nums[i] >= 0 && nums[i] + nums[j] > target) { + break; + } if (j > i + 1 && nums[j - 1] == nums[j]) { // 对nums[j]去重 continue; @@ -274,7 +274,7 @@ class Solution { int left = j + 1; int right = nums.length - 1; while (right > left) { - // nums[k] + nums[i] + nums[left] + nums[right] > target int会溢出 + // nums[j] + nums[i] + nums[left] + nums[right] int 可能会溢出,需要转为 long long sum = (long) nums[i] + nums[j] + nums[left] + nums[right]; if (sum > target) { right--; From 43d28e6bd3fa92f45a18dc00da7cd2470e0872f7 Mon Sep 17 00:00:00 2001 From: markwang Date: Wed, 7 Aug 2024 17:06:16 +0800 Subject: [PATCH 09/27] =?UTF-8?q?343.=E6=95=B4=E6=95=B0=E6=8B=86=E5=88=86?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0Go=E8=B4=AA=E5=BF=83=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0343.整数拆分.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/problems/0343.整数拆分.md b/problems/0343.整数拆分.md index 205b2201..7295627f 100644 --- a/problems/0343.整数拆分.md +++ b/problems/0343.整数拆分.md @@ -309,6 +309,8 @@ class Solution: ``` ### Go + +动态规划 ```go func integerBreak(n int) int { /** @@ -338,6 +340,28 @@ func max(a, b int) int{ } ``` +贪心 +```go +func integerBreak(n int) int { + if n == 2 { + return 1 + } + if n == 3 { + return 2 + } + if n == 4 { + return 4 + } + result := 1 + for n > 4 { + result *= 3 + n -= 3 + } + result *= n + return result +} +``` + ### Javascript ```Javascript var integerBreak = function(n) { From 00405e519283b681daca6bb0f9dc5d292c1cc9ab Mon Sep 17 00:00:00 2001 From: Allen Guo Date: Wed, 7 Aug 2024 07:13:31 -0700 Subject: [PATCH 10/27] =?UTF-8?q?=E6=9B=B4=E6=96=B00094.=E5=9F=8E=E5=B8=82?= =?UTF-8?q?=E9=97=B4=E8=B4=A7=E7=89=A9=E8=BF=90=E8=BE=93I.md=20Java?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0094.城市间货物运输I.md | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/problems/kamacoder/0094.城市间货物运输I.md b/problems/kamacoder/0094.城市间货物运输I.md index f72bfc00..45ca1313 100644 --- a/problems/kamacoder/0094.城市间货物运输I.md +++ b/problems/kamacoder/0094.城市间货物运输I.md @@ -392,6 +392,63 @@ Bellman_ford 是可以计算 负权值的单源最短路算法。 ## 其他语言版本 ### Java +```Java +public class Main { + + // Define an inner class Edge + static class Edge { + int from; + int to; + int val; + public Edge(int from, int to, int val) { + this.from = from; + this.to = to; + this.val = val; + } + } + + public static void main(String[] args) { + // Input processing + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int m = sc.nextInt(); + List edges = new ArrayList<>(); + + for (int i = 0; i < m; i++) { + int from = sc.nextInt(); + int to = sc.nextInt(); + int val = sc.nextInt(); + edges.add(new Edge(from, to, val)); + } + + // Represents the minimum distance from the current node to the original node + int[] minDist = new int[n + 1]; + + // Initialize the minDist array + Arrays.fill(minDist, Integer.MAX_VALUE); + minDist[1] = 0; + + // Starts the loop to relax all edges n - 1 times to update minDist array + for (int i = 1; i < n; i++) { + + for (Edge edge : edges) { + // Updates the minDist array + if (minDist[edge.from] != Integer.MAX_VALUE && (minDist[edge.from] + edge.val) < minDist[edge.to]) { + minDist[edge.to] = minDist[edge.from] + edge.val; + } + } + } + + // Outcome printing + if (minDist[n] == Integer.MAX_VALUE) { + System.out.println("unconnected"); + } else { + System.out.println(minDist[n]); + } + } +} + +``` ### Python From 2ecb6a5e71a40e6cae9f02c8bb0755f4ba8249d0 Mon Sep 17 00:00:00 2001 From: Allen Guo Date: Wed, 7 Aug 2024 10:16:28 -0700 Subject: [PATCH 11/27] =?UTF-8?q?=E6=9B=B4=E6=96=B00094.=E5=9F=8E=E5=B8=82?= =?UTF-8?q?=E9=97=B4=E8=B4=A7=E7=89=A9=E8=BF=90=E8=BE=93I-SPFA=20Java?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0094.城市间货物运输I-SPFA.md | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/problems/kamacoder/0094.城市间货物运输I-SPFA.md b/problems/kamacoder/0094.城市间货物运输I-SPFA.md index 07317d6b..ce383919 100644 --- a/problems/kamacoder/0094.城市间货物运输I-SPFA.md +++ b/problems/kamacoder/0094.城市间货物运输I-SPFA.md @@ -352,6 +352,77 @@ SPFA(队列优化版Bellman_ford) 在理论上 时间复杂度更胜一筹 ## 其他语言版本 ### Java +```Java +import java.util.*; + +public class Main { + + // Define an inner class Edge + static class Edge { + int from; + int to; + int val; + public Edge(int from, int to, int val) { + this.from = from; + this.to = to; + this.val = val; + } + } + + public static void main(String[] args) { + // Input processing + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int m = sc.nextInt(); + List> graph = new ArrayList<>(); + + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList<>()); + } + + for (int i = 0; i < m; i++) { + int from = sc.nextInt(); + int to = sc.nextInt(); + int val = sc.nextInt(); + graph.get(from).add(new Edge(from, to, val)); + } + + // Declare the minDist array to record the minimum distance form current node to the original node + int[] minDist = new int[n + 1]; + Arrays.fill(minDist, Integer.MAX_VALUE); + minDist[1] = 0; + + // Declare a queue to store the updated nodes instead of traversing all nodes each loop for more efficiency + Queue queue = new LinkedList<>(); + queue.offer(1); + + // Declare a boolean array to record if the current node is in the queue to optimise the processing + boolean[] isInQueue = new boolean[n + 1]; + + while (!queue.isEmpty()) { + int curNode = queue.poll(); + isInQueue[curNode] = false; // Represents the current node is not in the queue after being polled + for (Edge edge : graph.get(curNode)) { + if (minDist[edge.to] > minDist[edge.from] + edge.val) { // Start relaxing the edge + minDist[edge.to] = minDist[edge.from] + edge.val; + if (!isInQueue[edge.to]) { // Don't add the node if it's already in the queue + queue.offer(edge.to); + isInQueue[edge.to] = true; + } + } + } + } + + // Outcome printing + if (minDist[n] == Integer.MAX_VALUE) { + System.out.println("unconnected"); + } else { + System.out.println(minDist[n]); + } + } +} + +``` ### Python From a1365a6017da35ed336b3e1546a7a9fda167696b Mon Sep 17 00:00:00 2001 From: Taylor Zhu Date: Wed, 7 Aug 2024 17:46:03 -0700 Subject: [PATCH 12/27] =?UTF-8?q?Update=200232.=E7=94=A8=E6=A0=88=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E9=98=9F=E5=88=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ”模式“ -> ”模拟“ --- problems/0232.用栈实现队列.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index e8a3d2ec..7017107b 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -44,7 +44,7 @@ queue.empty(); // 返回 false 这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。 -使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。 +使用栈来模拟队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。 下面动画模拟以下队列的执行过程: From d90d5fbdca5a82420521a960fc04f8fe067aaacf Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Thu, 8 Aug 2024 14:07:41 +0800 Subject: [PATCH 13/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910104.=E5=BB=BA=E9=80=A0=E6=9C=80=E5=A4=A7=E5=B2=9B?= =?UTF-8?q?=E5=B1=BF=20JS=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0104.建造最大岛屿.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/problems/kamacoder/0104.建造最大岛屿.md b/problems/kamacoder/0104.建造最大岛屿.md index 7d67b7fc..d1f27e6d 100644 --- a/problems/kamacoder/0104.建造最大岛屿.md +++ b/problems/kamacoder/0104.建造最大岛屿.md @@ -372,6 +372,123 @@ public class 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 // 访问过的节点, 标记岛屿 +const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向 + +let count = 0 // 统计岛屿面积 +let areaMap = new Map() // 存储岛屿面积 + + +// 读取输入,初始化地图 +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(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 {*} visited 可访问节点 + * @param {*} x 开始搜索节点的下标 + * @param {*} y 开始搜索节点的下标 + * @param {*} mark 当前岛屿的标记 + * @return {*} + */ +const dfs = (graph, visited, x, y, mark) => { + if (visited[x][y] != 0) return + visited[x][y] = mark + count++ + + 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] != 0 || graph[nextx][nexty] == 0) continue + + dfs(graph, visited, nextx, nexty, mark) + } +} + +(async function () { + + // 读取输入,初始化地图 + await initGraph() + + let isAllLand = true //标记整个地图都是陆地 + + let mark = 2 // 标记岛屿 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (graph[i][j] == 0 && isAllLand) isAllLand = false + if (graph[i][j] === 1 && visited[i][j] === 0) { + count = 0 + dfs(graph, visited, i, j, mark) + areaMap.set(mark, count) + mark++ + } + } + } + + // 如果全是陆地, 直接返回面积 + if (isAllLand) { + console.log(N * M); + return + } + + let result = 0 // 记录最后结果 + let visitedIsland = new Map() //标记访问过的岛屿, 因为海洋四周可能是同一个岛屿, 需要标记避免重复统计面积 + for (let i = 0; i < N; i++) { + for (let j = 0; j < M; j++) { + if (visited[i][j] === 0) { + count = 1 // 记录连接之后的岛屿数量 + visitedIsland.clear() // 每次使用时,清空 + + // 计算海洋周围岛屿面积 + for (let m = 0; m < 4; m++) { + const nextx = i + dir[m][0] + const nexty = j + dir[m][1] + if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue //越界, 跳过 + + const island = visited[nextx][nexty] + if (island == 0 || visitedIsland.get(island)) continue// 四周是海洋或者访问过的陆地 跳过 + + // 标记为访问, 计算面积 + visitedIsland.set(island, true) + count += areaMap.get(visited[nextx][nexty]) + } + + result = Math.max(result, count) + } + } + } + + console.log(result); +})() +``` + + + ### TypeScript ### PhP From aff4169f1cd5248411021027cd176002f6b5a378 Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Thu, 8 Aug 2024 14:11:08 +0800 Subject: [PATCH 14/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910107.=E5=AF=BB=E6=89=BE=E5=AD=98=E5=9C=A8=E7=9A=84?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20JS=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0107.寻找存在的路径.md | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/problems/kamacoder/0107.寻找存在的路径.md b/problems/kamacoder/0107.寻找存在的路径.md index 906609c9..97b2714c 100644 --- a/problems/kamacoder/0107.寻找存在的路径.md +++ b/problems/kamacoder/0107.寻找存在的路径.md @@ -168,6 +168,72 @@ int main() { ### Javascript +```java +const r1 = require('readline').createInterface({ input: process.stdin }); +// 创建readline接口 +let iter = r1[Symbol.asyncIterator](); +// 创建异步迭代器 +const readline = async () => (await iter.next()).value; + + +let N, M // 节点数和边数 +let source, destination // 起点 终点 +let father = [] // 并查集 + + +// 并查集初始化 +const init = () => { + for (let i = 1; i <= N; i++) father[i] = i; +} + +// 并查集里寻根的过程 +const find = (u) => { + return u == father[u] ? u : father[u] = find(father[u]) +} + +// 将v->u 这条边加入并查集 +const join = (u, v) => { + u = find(u) + v = find(v) + if (u == v) return // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回 + father[v] = u +} + +// 判断 u 和 v是否找到同一个根 +const isSame = (u, v) => { + u = find(u) + v = find(v) + return u == v +} + + +(async function () { + // 读取第一行输入 + let line = await readline(); + [N, M] = line.split(' ').map(Number); + + // 初始化并查集 + father = new Array(N) + init() + + // 读取边信息, 加入并查集 + for (let i = 0; i < M; i++) { + line = await readline() + line = line.split(' ').map(Number) + join(line[0], line[1]) + } + + // 读取起点和终点 + line = await readline(); //JS注意这里的冒号 + [source, destination] = line.split(' ').map(Number) + + if (isSame(source, destination)) return console.log(1); + console.log(0); +})() +``` + + + ### TypeScript ### PhP From 006fb935ffc246c2818d64d5efc3b55cb73e965e Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Thu, 8 Aug 2024 14:13:25 +0800 Subject: [PATCH 15/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910108.=E5=86=97=E4=BD=99=E8=BF=9E=E6=8E=A5=20JS?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0108.冗余连接.md | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/problems/kamacoder/0108.冗余连接.md b/problems/kamacoder/0108.冗余连接.md index 70884139..8acb2f10 100644 --- a/problems/kamacoder/0108.冗余连接.md +++ b/problems/kamacoder/0108.冗余连接.md @@ -141,6 +141,70 @@ 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 N // 节点数和边数 +let father = [] // 并查集 + + +// 并查集初始化 +const init = () => { + for (let i = 1; i <= N; i++) father[i] = i; +} + +// 并查集里寻根的过程 +const find = (u) => { + return u == father[u] ? u : father[u] = find(father[u]) +} + +// 将v->u 这条边加入并查集 +const join = (u, v) => { + u = find(u) + v = find(v) + if (u == v) return // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回 + father[v] = u +} + +// 判断 u 和 v是否找到同一个根 +const isSame = (u, v) => { + u = find(u) + v = find(v) + return u == v +} + + +(async function () { + // 读取第一行输入 + let line = await readline(); + N = Number(line); + + // 初始化并查集 + father = new Array(N) + init() + + // 读取边信息, 加入并查集 + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + + if (!isSame(line[0], line[1])) { + join(line[0], line[1]) + }else{ + console.log(line[0], line[1]); + break + } + } +})() +``` + + + ### TypeScript ### PhP From a2aefe49b28d1a3b2bf6fd6b3e1aba76b0e5522d Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Thu, 8 Aug 2024 14:18:08 +0800 Subject: [PATCH 16/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910109.=E5=86=97=E4=BD=99=E8=BF=9E=E6=8E=A5II=20JS?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0109.冗余连接II.md | 113 ++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/problems/kamacoder/0109.冗余连接II.md b/problems/kamacoder/0109.冗余连接II.md index b13daec7..62b319c3 100644 --- a/problems/kamacoder/0109.冗余连接II.md +++ b/problems/kamacoder/0109.冗余连接II.md @@ -254,6 +254,119 @@ 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 N // 节点数和边数 +let father = [] // 并查集 +let edges = [] // 边集 +let inDegree = [] // 入度 + + +// 并查集初始化 +const init = () => { + for (let i = 1; i <= N; i++) father[i] = i; +} + +// 并查集里寻根的过程 +const find = (u) => { + return u == father[u] ? u : father[u] = find(father[u]) +} + +// 将v->u 这条边加入并查集 +const join = (u, v) => { + u = find(u) + v = find(v) + if (u == v) return // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回 + father[v] = u +} + +// 判断 u 和 v是否找到同一个根 +const isSame = (u, v) => { + u = find(u) + v = find(v) + return u == v +} + +// 判断删除一条边后是不是树 +const isTreeAfterRemoveEdge = (edges, edge) => { + // 初始化并查集 + init() + + for (let i = 0; i < N; i++) { + if (i == edge) continue + if (isSame(edges[i][0], edges[i][1])) { // 构成有向环了,一定不是树 + return false + } + join(edges[i][0], edges[i][1]) + } + return true +} + +// 在有向图里找到删除的那条边, 使其成为树 +const getRemoveEdge = (edges) => { + // 初始化并查集 + init() + + for (let i = 0; i < N; i++) { + if (isSame(edges[i][0], edges[i][1])) { // 构成有向环了,就是要删除的边 + console.log(edges[i][0], edges[i][1]); + return + } else { + join(edges[i][0], edges[i][1]) + } + } +} + + +(async function () { + // 读取第一行输入 + let line = await readline(); + N = Number(line); + + // 读取边信息, 统计入度 + for (let i = 0; i < N; i++) { + line = await readline() + line = line.split(' ').map(Number) + + edges.push(line) + + inDegree[line[1]] = (inDegree[line[1]] || 0) + 1 + } + + // 找到入度为2的节点 + let vec = [] // 记录入度为2的边(如果有的话就两条边) + // 找入度为2的节点所对应的边,注意要倒序,因为优先删除最后出现的一条边 + for (let i = N - 1; i >= 0; i--) { + if (inDegree[edges[i][1]] == 2) { + vec.push(i) + } + } + + // 情况一、情况二 + if (vec.length > 0) { + // 放在vec里的边已经按照倒叙放的,所以这里就优先删vec[0]这条边 + if (isTreeAfterRemoveEdge(edges, vec[0])) { + console.log(edges[vec[0]][0], edges[vec[0]][1]); + } else { + console.log(edges[vec[1]][0], edges[vec[1]][1]); + } + return 0 + } + + // 情况三 + // 明确没有入度为2的情况,那么一定有有向环,找到构成环的边返回就可以了 + getRemoveEdge(edges) +})() +``` + + + ### TypeScript ### PhP From 047c57ab4063945aeca9b1032fe74e8f5d14a4e8 Mon Sep 17 00:00:00 2001 From: Allen Guo Date: Thu, 8 Aug 2024 09:34:28 -0700 Subject: [PATCH 17/27] =?UTF-8?q?=E6=9B=B4=E6=96=B00095.=E5=9F=8E=E5=B8=82?= =?UTF-8?q?=E9=97=B4=E8=B4=A7=E7=89=A9=E8=BF=90=E8=BE=93II=20=E5=9F=BA?= =?UTF-8?q?=E4=BA=8EDPFA=E7=89=88=E6=9C=AC=E7=9A=84Java=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0095.城市间货物运输II.md | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/problems/kamacoder/0095.城市间货物运输II.md b/problems/kamacoder/0095.城市间货物运输II.md index 5bc4be7b..6226eb01 100644 --- a/problems/kamacoder/0095.城市间货物运输II.md +++ b/problems/kamacoder/0095.城市间货物运输II.md @@ -244,6 +244,92 @@ int main() { ## 其他语言版本 ### Java +```Java +import java.util.*; + +public class Main { + // 基于SPFA方法 + // Define an inner class Edge + static class Edge { + int from; + int to; + int val; + public Edge(int from, int to, int val) { + this.from = from; + this.to = to; + this.val = val; + } + } + + public static void main(String[] args) { + // Input processing + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int m = sc.nextInt(); + List> graph = new ArrayList<>(); + + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList<>()); + } + + for (int i = 0; i < m; i++) { + int from = sc.nextInt(); + int to = sc.nextInt(); + int val = sc.nextInt(); + graph.get(from).add(new Edge(from, to, val)); + } + + // Declare the minDist array to record the minimum distance form current node to the original node + int[] minDist = new int[n + 1]; + Arrays.fill(minDist, Integer.MAX_VALUE); + minDist[1] = 0; + + // Declare a queue to store the updated nodes instead of traversing all nodes each loop for more efficiency + Queue queue = new LinkedList<>(); + queue.offer(1); + + // Declare an array to record the times each node has been offered in the queue + int[] count = new int[n + 1]; + count[1]++; + + // Declare a boolean array to record if the current node is in the queue to optimise the processing + boolean[] isInQueue = new boolean[n + 1]; + + // Declare a boolean value to check if there is a negative weight loop inside the graph + boolean flag = false; + + while (!queue.isEmpty()) { + int curNode = queue.poll(); + isInQueue[curNode] = false; // Represents the current node is not in the queue after being polled + for (Edge edge : graph.get(curNode)) { + if (minDist[edge.to] > minDist[edge.from] + edge.val) { // Start relaxing the edge + minDist[edge.to] = minDist[edge.from] + edge.val; + if (!isInQueue[edge.to]) { // Don't add the node if it's already in the queue + queue.offer(edge.to); + count[edge.to]++; + isInQueue[edge.to] = true; + } + + if (count[edge.to] == n) { // If some node has been offered in the queue more than n-1 times + flag = true; + while (!queue.isEmpty()) queue.poll(); + break; + } + } + } + } + + if (flag) { + System.out.println("circle"); + } else if (minDist[n] == Integer.MAX_VALUE) { + System.out.println("unconnected"); + } else { + System.out.println(minDist[n]); + } + } +} + +``` ### Python From d2163ac3f698a4f2f0c4077a40db4e81cab42e14 Mon Sep 17 00:00:00 2001 From: Allen Guo Date: Thu, 8 Aug 2024 09:43:47 -0700 Subject: [PATCH 18/27] =?UTF-8?q?=E6=9B=B4=E6=96=B00095.=E5=9F=8E=E5=B8=82?= =?UTF-8?q?=E9=97=B4=E8=B4=A7=E7=89=A9=E8=BF=90=E8=BE=93II=20=E5=9F=BA?= =?UTF-8?q?=E4=BA=8ESPFA=E7=89=88=E6=9C=AC=E7=9A=84Java=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0095.城市间货物运输II.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/kamacoder/0095.城市间货物运输II.md b/problems/kamacoder/0095.城市间货物运输II.md index 6226eb01..f1025e4a 100644 --- a/problems/kamacoder/0095.城市间货物运输II.md +++ b/problems/kamacoder/0095.城市间货物运输II.md @@ -248,7 +248,7 @@ int main() { import java.util.*; public class Main { - // 基于SPFA方法 + // 基于Bellman_ford-SPFA方法 // Define an inner class Edge static class Edge { int from; From ab6cb84cb905dc3ededa4165653435afd38c34ed Mon Sep 17 00:00:00 2001 From: Allen Guo Date: Thu, 8 Aug 2024 17:14:40 -0700 Subject: [PATCH 19/27] =?UTF-8?q?=E6=9B=B4=E6=96=B00096.=E5=9F=8E=E5=B8=82?= =?UTF-8?q?=E9=97=B4=E8=B4=A7=E7=89=A9=E8=BF=90=E8=BE=93III=20=E5=9F=BA?= =?UTF-8?q?=E4=BA=8EBellman=5Fford=E4=B8=80=E8=88=AC=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 --- .../0096.城市间货物运输III.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/problems/kamacoder/0096.城市间货物运输III.md b/problems/kamacoder/0096.城市间货物运输III.md index feaaa1f3..dacd23d1 100644 --- a/problems/kamacoder/0096.城市间货物运输III.md +++ b/problems/kamacoder/0096.城市间货物运输III.md @@ -636,6 +636,71 @@ dijkstra 是贪心的思路 每一次搜索都只会找距离源点最近的非 ## 其他语言版本 ### Java +```Java +import java.util.*; + +public class Main { + // 基于Bellman_for一般解法解决单源最短路径问题 + // Define an inner class Edge + static class Edge { + int from; + int to; + int val; + public Edge(int from, int to, int val) { + this.from = from; + this.to = to; + this.val = val; + } + } + + public static void main(String[] args) { + // Input processing + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int m = sc.nextInt(); + + List graph = new ArrayList<>(); + + for (int i = 0; i < m; i++) { + int from = sc.nextInt(); + int to = sc.nextInt(); + int val = sc.nextInt(); + graph.add(new Edge(from, to, val)); + } + + int src = sc.nextInt(); + int dst = sc.nextInt(); + int k = sc.nextInt(); + + int[] minDist = new int[n + 1]; + int[] minDistCopy; + + Arrays.fill(minDist, Integer.MAX_VALUE); + minDist[src] = 0; + + for (int i = 0; i < k + 1; i++) { // Relax all edges k + 1 times + minDistCopy = Arrays.copyOf(minDist, n + 1); + for (Edge edge : graph) { + int from = edge.from; + int to = edge.to; + int val = edge.val; + // Use minDistCopy to calculate minDist + if (minDistCopy[from] != Integer.MAX_VALUE && minDist[to] > minDistCopy[from] + val) { + minDist[to] = minDistCopy[from] + val; + } + } + } + + // Output printing + if (minDist[dst] == Integer.MAX_VALUE) { + System.out.println("unreachable"); + } else { + System.out.println(minDist[dst]); + } + } +} + +``` ### Python From 93c206794beafcf6c2416e59291351984982e2b9 Mon Sep 17 00:00:00 2001 From: markwang Date: Fri, 9 Aug 2024 14:22:09 +0800 Subject: [PATCH 20/27] =?UTF-8?q?01=E8=83=8C=E5=8C=85-2=E5=A2=9E=E5=8A=A0G?= =?UTF-8?q?o=E4=B8=80=E7=BB=B4=E6=95=B0=E7=BB=84,=E4=BA=8C=E7=BB=B4?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E7=A7=BB=E8=87=B3-1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/背包理论基础01背包-1.md | 52 +++++++++++++++++++ problems/背包理论基础01背包-2.md | 63 +++++++++++------------- 2 files changed, 81 insertions(+), 34 deletions(-) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index 0c78e3f6..6b9be72d 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -437,6 +437,58 @@ print(dp[n - 1][bagweight]) ### Go ```go +package main + +import ( + "fmt" +) + +func main() { + var n, bagweight int // bagweight代表行李箱空间 + fmt.Scan(&n, &bagweight) + + weight := make([]int, n) // 存储每件物品所占空间 + value := make([]int, n) // 存储每件物品价值 + + for i := 0; i < n; i++ { + fmt.Scan(&weight[i]) + } + for j := 0; j < n; j++ { + fmt.Scan(&value[j]) + } + // dp数组, dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值 + dp := make([][]int, n) + for i := range dp { + dp[i] = make([]int, bagweight+1) + } + + // 初始化, 因为需要用到dp[i - 1]的值 + // j < weight[0]已在上方被初始化为0 + // j >= weight[0]的值就初始化为value[0] + for j := weight[0]; j <= bagweight; j++ { + dp[0][j] = value[0] + } + + for i := 1; i < n; i++ { // 遍历科研物品 + for j := 0; j <= bagweight; j++ { // 遍历行李箱容量 + if j < weight[i] { + dp[i][j] = dp[i-1][j] // 如果装不下这个物品,那么就继承dp[i - 1][j]的值 + } else { + dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]) + } + } + } + + fmt.Println(dp[n-1][bagweight]) +} + +func max(x, y int) int { + if x > y { + return x + } + return y +} + ``` ### Javascript diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index c61a72cc..6485da1f 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -318,50 +318,45 @@ print(dp[n - 1][bagweight]) package main import ( - "fmt" + "fmt" ) func main() { - var n, bagweight int - fmt.Scan(&n, &bagweight) + // 读取 M 和 N + var M, N int + fmt.Scan(&M, &N) - weight := make([]int, n) - value := make([]int, n) + costs := make([]int, M) + values := make([]int, M) - for i := 0; i < n; i++ { - fmt.Scan(&weight[i]) - } - for j := 0; j < n; j++ { - fmt.Scan(&value[j]) - } + for i := 0; i < M; i++ { + fmt.Scan(&costs[i]) + } + for j := 0; j < M; j++ { + fmt.Scan(&values[j]) + } - dp := make([][]int, n) - for i := range dp { - dp[i] = make([]int, bagweight+1) - } + // 创建一个动态规划数组dp,初始值为0 + dp := make([]int, N + 1) - for j := weight[0]; j <= bagweight; j++ { - dp[0][j] = value[0] - } + // 外层循环遍历每个类型的研究材料 + for i := 0; i < M; i++ { + // 内层循环从 N 空间逐渐减少到当前研究材料所占空间 + for j := N; j >= costs[i]; j-- { + // 考虑当前研究材料选择和不选择的情况,选择最大值 + dp[j] = max(dp[j], dp[j-costs[i]] + values[i]) + } + } - for i := 1; i < n; i++ { - for j := 0; j <= bagweight; j++ { - if j < weight[i] { - dp[i][j] = dp[i-1][j] - } else { - dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]) - } - } - } - - fmt.Println(dp[n-1][bagweight]) + // 输出dp[N],即在给定 N 行李空间可以携带的研究材料最大价值 + fmt.Println(dp[N]) } -func max(a, b int) int { - if a > b { - return a - } - return b +func max(x, y int) int { + if x > y { + return x + } + return y } ``` From bb2803ce967080ca6274b854458176a345b5fcee Mon Sep 17 00:00:00 2001 From: markwang Date: Fri, 9 Aug 2024 15:05:17 +0800 Subject: [PATCH 21/27] =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/背包理论基础01背包-1.md | 72 ++++++++++++------------ problems/背包理论基础01背包-2.md | 58 +++++++++---------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index 6b9be72d..352b301a 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -440,53 +440,53 @@ print(dp[n - 1][bagweight]) package main import ( - "fmt" + "fmt" ) func main() { - var n, bagweight int // bagweight代表行李箱空间 - fmt.Scan(&n, &bagweight) + var n, bagweight int // bagweight代表行李箱空间 + fmt.Scan(&n, &bagweight) - weight := make([]int, n) // 存储每件物品所占空间 - value := make([]int, n) // 存储每件物品价值 + weight := make([]int, n) // 存储每件物品所占空间 + value := make([]int, n) // 存储每件物品价值 - for i := 0; i < n; i++ { - fmt.Scan(&weight[i]) - } - for j := 0; j < n; j++ { - fmt.Scan(&value[j]) - } - // dp数组, dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值 - dp := make([][]int, n) - for i := range dp { - dp[i] = make([]int, bagweight+1) - } + for i := 0; i < n; i++ { + fmt.Scan(&weight[i]) + } + for j := 0; j < n; j++ { + fmt.Scan(&value[j]) + } + // dp数组, dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值 + dp := make([][]int, n) + for i := range dp { + dp[i] = make([]int, bagweight + 1) + } - // 初始化, 因为需要用到dp[i - 1]的值 - // j < weight[0]已在上方被初始化为0 - // j >= weight[0]的值就初始化为value[0] - for j := weight[0]; j <= bagweight; j++ { - dp[0][j] = value[0] - } + // 初始化, 因为需要用到dp[i - 1]的值 + // j < weight[0]已在上方被初始化为0 + // j >= weight[0]的值就初始化为value[0] + for j := weight[0]; j <= bagweight; j++ { + dp[0][j] = value[0] + } - for i := 1; i < n; i++ { // 遍历科研物品 - for j := 0; j <= bagweight; j++ { // 遍历行李箱容量 - if j < weight[i] { - dp[i][j] = dp[i-1][j] // 如果装不下这个物品,那么就继承dp[i - 1][j]的值 - } else { - dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]) - } - } - } + for i := 1; i < n; i++ { // 遍历科研物品 + for j := 0; j <= bagweight; j++ { // 遍历行李箱容量 + if j < weight[i] { + dp[i][j] = dp[i-1][j] // 如果装不下这个物品,那么就继承dp[i - 1][j]的值 + } else { + dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]) + } + } + } - fmt.Println(dp[n-1][bagweight]) + fmt.Println(dp[n-1][bagweight]) } func max(x, y int) int { - if x > y { - return x - } - return y + if x > y { + return x + } + return y } ``` diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index 6485da1f..cd8f317c 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -313,50 +313,50 @@ for i in range(1, n): print(dp[n - 1][bagweight]) ``` -### Go +### Go ```go package main import ( - "fmt" + "fmt" ) func main() { - // 读取 M 和 N - var M, N int - fmt.Scan(&M, &N) + // 读取 M 和 N + var M, N int + fmt.Scan(&M, &N) - costs := make([]int, M) - values := make([]int, M) + costs := make([]int, M) + values := make([]int, M) - for i := 0; i < M; i++ { - fmt.Scan(&costs[i]) - } - for j := 0; j < M; j++ { - fmt.Scan(&values[j]) - } + for i := 0; i < M; i++ { + fmt.Scan(&costs[i]) + } + for j := 0; j < M; j++ { + fmt.Scan(&values[j]) + } - // 创建一个动态规划数组dp,初始值为0 - dp := make([]int, N + 1) + // 创建一个动态规划数组dp,初始值为0 + dp := make([]int, N + 1) - // 外层循环遍历每个类型的研究材料 - for i := 0; i < M; i++ { - // 内层循环从 N 空间逐渐减少到当前研究材料所占空间 - for j := N; j >= costs[i]; j-- { - // 考虑当前研究材料选择和不选择的情况,选择最大值 - dp[j] = max(dp[j], dp[j-costs[i]] + values[i]) - } - } + // 外层循环遍历每个类型的研究材料 + for i := 0; i < M; i++ { + // 内层循环从 N 空间逐渐减少到当前研究材料所占空间 + for j := N; j >= costs[i]; j-- { + // 考虑当前研究材料选择和不选择的情况,选择最大值 + dp[j] = max(dp[j], dp[j-costs[i]] + values[i]) + } + } - // 输出dp[N],即在给定 N 行李空间可以携带的研究材料最大价值 - fmt.Println(dp[N]) + // 输出dp[N],即在给定 N 行李空间可以携带的研究材料最大价值 + fmt.Println(dp[N]) } func max(x, y int) int { - if x > y { - return x - } - return y + if x > y { + return x + } + return y } ``` From d71abfa7f6001df1d7be95b2df790651a57cc0ee Mon Sep 17 00:00:00 2001 From: kyshen Date: Fri, 9 Aug 2024 22:53:20 +0800 Subject: [PATCH 22/27] feat: 0105 python BFS solution --- .../0105.有向图的完全可达性.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/problems/kamacoder/0105.有向图的完全可达性.md b/problems/kamacoder/0105.有向图的完全可达性.md index 226d0f13..cd880a83 100644 --- a/problems/kamacoder/0105.有向图的完全可达性.md +++ b/problems/kamacoder/0105.有向图的完全可达性.md @@ -290,6 +290,42 @@ int main() { ### Java ### Python +BFS算法 +```Python +import collections + +path = set() # 纪录 BFS 所经过之节点 + +def bfs(root, graph): + global path + + que = collections.deque([root]) + while que: + cur = que.popleft() + path.add(cur) + + for nei in graph[cur]: + que.append(nei) + graph[cur] = [] + return + +def main(): + N, K = map(int, input().strip().split()) + graph = collections.defaultdict(list) + for _ in range(K): + src, dest = map(int, input().strip().split()) + graph[src].append(dest) + + bfs(1, graph) + if path == {i for i in range(1, N + 1)}: + return 1 + return -1 + + +if __name__ == "__main__": + print(main()) + +``` ### Go From a868ae4d2e985da8abe18a1d9e91378a305bc8ce Mon Sep 17 00:00:00 2001 From: SecondaryRainbow <927497402@qq.com> Date: Sun, 11 Aug 2024 20:40:35 +0800 Subject: [PATCH 23/27] =?UTF-8?q?977=E9=A2=98=E7=9B=B8=E5=85=B3=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改了977题Go语言代码附近的格式,以及C#代码附近的格式,使其能够正常显示。(原本Go与python代码合到一起了) --- problems/0977.有序数组的平方.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/problems/0977.有序数组的平方.md b/problems/0977.有序数组的平方.md index 7119dda5..effa9055 100644 --- a/problems/0977.有序数组的平方.md +++ b/problems/0977.有序数组的平方.md @@ -207,6 +207,7 @@ class Solution: new_list.append(nums[left] ** 2) left += 1 return new_list[::-1] +``` ### Go: @@ -539,7 +540,7 @@ public class Solution { return result; } } - +``` C# LINQ: ```csharp public class Solution { @@ -553,3 +554,4 @@ public class Solution { + From 49aa077428baef0079a7ef22e82b8a113eca4f40 Mon Sep 17 00:00:00 2001 From: liujiahang Date: Mon, 12 Aug 2024 00:57:42 +0800 Subject: [PATCH 24/27] =?UTF-8?q?=E8=AE=A2=E6=AD=A3=E6=96=87=E4=BB=B60099.?= =?UTF-8?q?=E5=B2=9B=E5=B1=BF=E7=9A=84=E6=95=B0=E9=87=8F=E5=B9=BF=E6=90=9C?= =?UTF-8?q?.md=E6=96=87=E4=BB=B6=EF=BC=8Cpython=E9=83=A8=E5=88=86=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E6=98=AF=E6=B7=B1=E6=90=9C=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kamacoder/0099.岛屿的数量广搜.md | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/problems/kamacoder/0099.岛屿的数量广搜.md b/problems/kamacoder/0099.岛屿的数量广搜.md index 3c069b44..9771877b 100644 --- a/problems/kamacoder/0099.岛屿的数量广搜.md +++ b/problems/kamacoder/0099.岛屿的数量广搜.md @@ -246,29 +246,36 @@ public class Main { ```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) +from collections import deque +directions = [[0, 1], [1, 0], [0, -1], [-1, 0]] +def bfs(grid, visited, x, y): + que = deque([]) + que.append([x,y]) + while que: + cur_x, cur_y = que.popleft() + for i, j in directions: + next_x = cur_x + i + next_y = cur_y + j + if next_y < 0 or next_x < 0 or next_x >= len(grid) 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 + que.append([next_x, next_y]) + def main(): n, m = map(int, input().split()) - grid = [list(map(int, input().split())) for _ in range(n)] + grid = [] + for i in range(n): + grid.append(list(map(int, input().split()))) visited = [[False] * m for _ in range(n)] - - result = 0 + res = 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 grid[i][j] == 1 and not visited[i][j]: + res += 1 + bfs(grid, visited, i, j) + print(res) if __name__ == "__main__": main() From 06d15bb5917f61112388154b6db63e55e9f647f2 Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Tue, 13 Aug 2024 09:14:53 +0800 Subject: [PATCH 25/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910110.=E5=AD=97=E7=AC=A6=E4=B8=B2=E6=8E=A5=E9=BE=99=20J?= =?UTF-8?q?S=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0110.字符串接龙.md | 76 +++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/problems/kamacoder/0110.字符串接龙.md b/problems/kamacoder/0110.字符串接龙.md index feeec6dd..b96290b6 100644 --- a/problems/kamacoder/0110.字符串接龙.md +++ b/problems/kamacoder/0110.字符串接龙.md @@ -38,7 +38,7 @@ ebc dec dfc yhn -``` +``` 输出示例 @@ -224,6 +224,80 @@ public class 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 N //输入字符串个数 +let beginStr //开始字符串 +let endStr //结束字符串 +let strSet = new Set() //字符串集合 +let visitedMap = new Map() //访问过的字符串 + +// 读取输入,初始化地图 +const init = async () => { + let line = await readline(); + line = line.trim() + N = Number(line); + + line = await readline(); + line = line.trim().split(' ') + beginStr = line[0] + endStr = line[1] + + for (let i = 0; i < N; i++) { + line = await readline() + line = line.trim() + strSet.add(line.trim()) + } +} + +(async function () { + + // 读取输入,初始化数据 + await init() + + // 初始化队列 + let queue = [] + queue.push(beginStr) + + // 初始化visitMap + visitedMap.set(beginStr, 1) + + while (queue.length) { + let word = queue.shift() + let path = visitedMap.get(word) + + // 遍历26个字母 + for (let i = 0; i < word.length; i++) { + let newWord = word.split('') // 用一个新字符串替换str,因为每次要置换一个字符 + for (let j = 0; j < 26; j++) { + newWord[i] = String.fromCharCode('a'.charCodeAt() + j) + // 发现替换字母后,字符串与终点字符串相同 + if (newWord.join('') === endStr) { + console.log(path + 1); + return 0; // 找到了路径 + } + + // 字符串集合里出现了newWord,并且newWord没有被访问过 + if (strSet.has(newWord.join('')) && !visitedMap.has(newWord.join(''))) { + // 添加访问信息,并将新字符串放到队列中 + queue.push(newWord.join('')) + visitedMap.set(newWord.join(''), path + 1) + } + } + } + } + + console.log(0); +})() +``` + + + ### TypeScript ### PhP From ce3995c8fd6f5a98ca2ac4a94ad1d70d8d42a88e Mon Sep 17 00:00:00 2001 From: wangya <1264178545@qq.com> Date: Tue, 13 Aug 2024 09:26:26 +0800 Subject: [PATCH 26/27] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=8D=A1=E7=A0=81?= =?UTF-8?q?=E7=BD=910117.=E8=BD=AF=E4=BB=B6=E6=9E=84=E5=BB=BA=20JS?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/kamacoder/0117.软件构建.md | 76 ++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/problems/kamacoder/0117.软件构建.md b/problems/kamacoder/0117.软件构建.md index 05cb7358..bb0c9aec 100644 --- a/problems/kamacoder/0117.软件构建.md +++ b/problems/kamacoder/0117.软件构建.md @@ -193,7 +193,7 @@ 理解思想后,确实不难,但代码写起来也不容易。 -为了每次可以找到所有节点的入度信息,我们要在初始话的时候,就把每个节点的入度 和 每个节点的依赖关系做统计。 +为了每次可以找到所有节点的入度信息,我们要在初始化的时候,就把每个节点的入度 和 每个节点的依赖关系做统计。 代码如下: @@ -451,6 +451,80 @@ 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 N, M // 节点数和边数 +let inDegrees = [] // 入度 +let umap = new Map() // 记录文件依赖关系 +let result = [] // 结果 + + +// 根据输入, 初始化数据 +const init = async () => { + // 读取第一行输入 + let line = await readline(); + [N, M] = line.split(' ').map(Number) + + inDegrees = new Array(N).fill(0) + + // 读取边集 + while (M--) { + line = await readline(); + let [x, y] = line.split(' ').map(Number) + + // 记录入度 + inDegrees[y]++ + + // 记录x指向哪些文件 + if (!umap.has(x)) { + umap.set(x, [y]) + } else { + umap.get(x).push(y) + } + } +} + +(async function () { + // 根据输入, 初始化数据 + await init() + + let queue = [] // 入度为0的节点 + for (let i = 0; i < N; i++) { + if (inDegrees[i] == 0) { + queue.push(i) + } + } + + while (queue.length) { + let cur = queue.shift() //当前文件 + + result.push(cur) + + let files = umap.get(cur) // 当前文件指向的文件 + + // 当前文件指向的文件入度减1 + if (files && files.length) { + for (let i = 0; i < files.length; i++) { + inDegrees[files[i]]-- + if (inDegrees[files[i]] == 0) queue.push(files[i]) + } + } + } + + // 这里result.length == N 一定要判断, 因为可能存在环 + if (result.length == N) return console.log(result.join(' ')) + console.log(-1) +})() +``` + + + ### TypeScript ### PhP From 418168efafe7e85f556e35b476aa8fbcb73f404b Mon Sep 17 00:00:00 2001 From: HJHuangUM <57804285+Wogwan@users.noreply.github.com> Date: Sun, 18 Aug 2024 18:05:53 -0700 Subject: [PATCH 27/27] update Python solutions for kama102 and kama104 Provide BFS solution --- problems/kamacoder/0102.沉没孤岛.md | 57 ++++++++++++ problems/kamacoder/0104.建造最大岛屿.md | 87 +++++++++++++++++++ 2 files changed, 144 insertions(+) diff --git a/problems/kamacoder/0102.沉没孤岛.md b/problems/kamacoder/0102.沉没孤岛.md index 2b16da04..eec12e5f 100644 --- a/problems/kamacoder/0102.沉没孤岛.md +++ b/problems/kamacoder/0102.沉没孤岛.md @@ -140,6 +140,63 @@ int main() { ### Python +#### 广搜版 +```Python +from collections import deque + +n, m = list(map(int, input().split())) +g = [] +for _ in range(n): + row = list(map(int,input().split())) + g.append(row) + +directions = [(1,0),(-1,0),(0,1),(0,-1)] +count = 0 + +def bfs(r,c,mode): + global count + q = deque() + q.append((r,c)) + count += 1 + + while q: + r, c = q.popleft() + if mode: + g[r][c] = 2 + + for di in directions: + next_r = r + di[0] + next_c = c + di[1] + if next_c < 0 or next_c >= m or next_r < 0 or next_r >= n: + continue + if g[next_r][next_c] == 1: + q.append((next_r,next_c)) + if mode: + g[r][c] = 2 + + count += 1 + + +for i in range(n): + if g[i][0] == 1: bfs(i,0,True) + if g[i][m-1] == 1: bfs(i, m-1,True) + +for j in range(m): + if g[0][j] == 1: bfs(0,j,1) + if g[n-1][j] == 1: bfs(n-1,j,1) + +for i in range(n): + for j in range(m): + if g[i][j] == 2: + g[i][j] = 1 + else: + g[i][j] = 0 + +for row in g: + print(" ".join(map(str, row))) +``` + + ### Go ### Rust diff --git a/problems/kamacoder/0104.建造最大岛屿.md b/problems/kamacoder/0104.建造最大岛屿.md index 7132217b..cd647d5e 100644 --- a/problems/kamacoder/0104.建造最大岛屿.md +++ b/problems/kamacoder/0104.建造最大岛屿.md @@ -366,6 +366,93 @@ public class Main { ### Python + +#### BFS +```Python +from typing import List +from collections import defaultdict + +class Solution: + def __init__(self): + self.direction = [(1,0),(-1,0),(0,1),(0,-1)] + self.res = 0 + self.count = 0 + self.idx = 1 + self.count_area = defaultdict(int) + + def max_area_island(self, grid: List[List[int]]) -> int: + if not grid or len(grid) == 0 or len(grid[0]) == 0: + return 0 + + for i in range(len(grid)): + for j in range(len(grid[0])): + if grid[i][j] == 1: + self.count = 0 + self.idx += 1 + self.dfs(grid,i,j) + # print(grid) + self.check_area(grid) + # print(self.count_area) + + if self.check_largest_connect_island(grid=grid): + return self.res + 1 + return max(self.count_area.values()) + + def dfs(self,grid,row,col): + grid[row][col] = self.idx + self.count += 1 + for dr,dc in self.direction: + _row = dr + row + _col = dc + col + if 0<=_row