diff --git a/.DS_Store b/.DS_Store
index f89600e9..f7ce0fd5 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md
index def69277..0b1622ac 100644
--- a/problems/0188.买卖股票的最佳时机IV.md
+++ b/problems/0188.买卖股票的最佳时机IV.md
@@ -404,6 +404,47 @@ func max188(a, b int) int {
}
```
+版本三:空间优化版本
+
+```go
+func maxProfit(k int, prices []int) int {
+ n := len(prices)
+ // k次交易,2 * k种状态
+ // 状态从1开始计算,避免判断
+ // 奇数时持有(保持或买入)
+ // 偶数时不持有(保持或卖出)
+ dp := make([][]int, 2)
+ dp[0] = make([]int, k * 2 + 1)
+ dp[1] = make([]int, k * 2 + 1)
+
+ // 奇数状态时持有,i += 2
+ for i := 1; i <= k * 2; i += 2 {
+ dp[0][i] = -prices[0]
+ }
+
+ for i := 1; i < len(prices); i++ {
+ for j := 1; j <= k * 2; j++ {
+ if j % 2 == 1 {
+ dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - 1] - prices[i])
+ } else {
+ dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j - 1] + prices[i])
+ }
+ }
+ }
+
+ return dp[(n - 1) % 2][k * 2]
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+
+
### JavaScript:
```javascript
@@ -558,3 +599,4 @@ impl Solution {
+
diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md
index 95689a48..4913b8bd 100644
--- a/problems/0309.最佳买卖股票时机含冷冻期.md
+++ b/problems/0309.最佳买卖股票时机含冷冻期.md
@@ -357,6 +357,42 @@ func max(a, b int) int {
}
```
+```go
+// 一维优化版本
+// 时间复杂度O(n), 空间复杂度O(1)
+func maxProfit(prices []int) int {
+
+ // 0: 持有,一直持有和买入
+ // 1: 不持有,一直不持有(不包含前一天卖出,因为这样的一天是冷静期,状态有区别)
+ // 2:不持有,今天卖出
+ // 3:冷静期,前一天卖出(一直不持有)
+ dp0, dp1, dp2, dp3 := -prices[0], 0, 0, 0
+
+ n := len(prices)
+
+ for i := 1; i < n; i++ {
+ t0 := max(dp0, max(dp1, dp3)-prices[i])
+ t1 := max(dp1, dp3)
+ t2 := dp0 + prices[i]
+ t3 := dp2
+
+ // 更新
+ dp0, dp1, dp2, dp3 = t0, t1, t2, t3
+ }
+
+ return max(dp1, max(dp2, dp3))
+}
+
+func max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+```
+
+
+
### Javascript:
> 不同的状态定义 感觉更容易理解些
@@ -540,3 +576,4 @@ impl Solution {
+
diff --git a/problems/0383.赎金信.md b/problems/0383.赎金信.md
index e8caa980..eb83d3ec 100644
--- a/problems/0383.赎金信.md
+++ b/problems/0383.赎金信.md
@@ -176,7 +176,7 @@ class Solution:
for x in ransomNote:
value = hashmap.get(x)
- if not value or not value:
+ if not value:
return False
else:
hashmap[x] -= 1
diff --git a/problems/0503.下一个更大元素II.md b/problems/0503.下一个更大元素II.md
index 62066d85..5751bb91 100644
--- a/problems/0503.下一个更大元素II.md
+++ b/problems/0503.下一个更大元素II.md
@@ -168,6 +168,7 @@ class Solution {
```
### Python:
+> 版本一:
```python
class Solution:
@@ -181,6 +182,34 @@ class Solution:
stack.append(i%len(nums))
return dp
```
+
+> 版本二:针对版本一的优化
+
+```python3
+class Solution:
+ def nextGreaterElements(self, nums: List[int]) -> List[int]:
+ res = [-1] * len(nums)
+ stack = []
+ #第一次遍历nums
+ for i, num in enumerate(nums):
+ while stack and num > nums[stack[-1]]:
+ res[stack[-1]] = num
+ stack.pop()
+ stack.append(i)
+ #此时stack仍有剩余,有部分数‘无下一个更大元素’待修正
+ #第二次遍历nums
+ for num in nums:
+ #一旦stack为空,就表明所有数都有下一个更大元素,可以返回结果
+ if not stack:
+ return res
+ while stack and num > nums[stack[-1]]:
+ res[stack[-1]] = num
+ stack.pop()
+ #不要将已经有下一个更大元素的数加入栈,这样会重复赋值,只需对第一次遍历剩余的数再尝试寻找下一个更大元素即可
+ #最后仍有部分最大数无法有下一个更大元素,返回结果
+ return res
+```
+
### Go:
```go
@@ -203,7 +232,6 @@ func nextGreaterElements(nums []int) []int {
return result
}
```
-
### JavaScript:
```JS
diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md
index 6b9e5834..25d39486 100644
--- a/problems/0701.二叉搜索树中的插入操作.md
+++ b/problems/0701.二叉搜索树中的插入操作.md
@@ -283,32 +283,10 @@ class Solution:
return TreeNode(val)
self.traversal(root, val)
return root
-
```
递归法(版本二)
```python
-class Solution:
- def insertIntoBST(self, root, val):
- if root is None:
- return TreeNode(val)
- parent = None
- cur = root
- while cur:
- parent = cur
- if val < cur.val:
- cur = cur.left
- else:
- cur = cur.right
- if val < parent.val:
- parent.left = TreeNode(val)
- else:
- parent.right = TreeNode(val)
- return root
-```
-
-递归法(版本三)
-```python
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root is None or root.val == val:
@@ -326,7 +304,7 @@ class Solution:
return root
```
-递归法(版本四)
+递归法(版本三)
```python
class Solution:
def insertIntoBST(self, root, val):
@@ -340,10 +318,9 @@ class Solution:
root.right = self.insertIntoBST(root.right, val)
return root
-
```
-迭代法
+迭代法(版本一)
```python
class Solution:
def insertIntoBST(self, root, val):
@@ -366,10 +343,53 @@ class Solution:
else:
parent.right = node # 将新节点连接到父节点的右子树
- return root
-
-
+ return root
```
+
+迭代法(版本二)
+```python
+class Solution:
+ def insertIntoBST(self, root, val):
+ if root is None:
+ return TreeNode(val)
+ parent = None
+ cur = root
+ while cur:
+ parent = cur
+ if val < cur.val:
+ cur = cur.left
+ else:
+ cur = cur.right
+ if val < parent.val:
+ parent.left = TreeNode(val)
+ else:
+ parent.right = TreeNode(val)
+ return root
+```
+
+迭代法(精简)
+```python
+class Solution:
+ def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
+ if not root: # 如果根节点为空,创建新节点作为根节点并返回
+ return TreeNode(val)
+ cur = root
+ while cur:
+ if val < cur.val:
+ if not cur.left: # 如果此时父节点的左子树为空
+ cur.left = TreeNode(val) # 将新节点连接到父节点的左子树
+ return root
+ else:
+ cur = cur.left
+ elif val > cur.val:
+ if not cur.right: # 如果此时父节点的左子树为空
+ cur.right = TreeNode(val) # 将新节点连接到父节点的右子树
+ return root
+ else:
+ cur = cur.right
+
+```
+
-----
### Go
diff --git a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md
index 73714147..b0e8b141 100644
--- a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md
+++ b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md
@@ -188,6 +188,20 @@ class Solution:
return max(dp[-1][0], dp[-1][1])
```
+```python
+class Solution:
+ def maxProfit(self, prices: List[int], fee: int) -> int:
+ # 持有股票手上的最大現金
+ hold = -prices[0] - fee
+ # 不持有股票手上的最大現金
+ not_hold = 0
+ for price in prices[1:]:
+ new_hold = max(hold, not_hold - price - fee)
+ new_not_hold = max(not_hold, hold + price)
+ hold, not_hold = new_hold, new_not_hold
+ return not_hold
+```
+
### Go:
```go
diff --git a/problems/1049.最后一块石头的重量II.md b/problems/1049.最后一块石头的重量II.md
index 4f2cc9e3..b40ed114 100644
--- a/problems/1049.最后一块石头的重量II.md
+++ b/problems/1049.最后一块石头的重量II.md
@@ -313,6 +313,8 @@ class Solution:
```
### Go:
+
+一维dp
```go
func lastStoneWeightII(stones []int) int {
// 15001 = 30 * 1000 /2 +1
@@ -341,6 +343,43 @@ func max(a, b int) int {
}
```
+二维dp
+```go
+func lastStoneWeightII(stones []int) int {
+ sum := 0
+ for _, val := range stones {
+ sum += val
+ }
+ target := sum / 2
+
+ dp := make([][]int, len(stones))
+ for i := range dp {
+ dp[i] = make([]int, target + 1)
+ }
+ for j := stones[0]; j <= target; j++ {
+ dp[0][j] = stones[0]
+ }
+
+ for i := 1; i < len(stones); i++ {
+ for j := 0; j <= target; j++ {
+ if stones[i] > j {
+ dp[i][j] = dp[i-1][j]
+ } else {
+ dp[i][j] = max(dp[i-1][j], dp[i-1][j-stones[i]] + stones[i])
+ }
+ }
+ }
+ return (sum - dp[len(stones)-1][target]) - dp[len(stones)-1][target]
+}
+
+func max(x, y int) int {
+ if x > y {
+ return x
+ }
+ return y
+}
+```
+
### JavaScript:
```javascript
diff --git a/problems/kamacoder/0044.开发商购买土地.md b/problems/kamacoder/0044.开发商购买土地.md
index 37bb98ed..ea2c696e 100644
--- a/problems/kamacoder/0044.开发商购买土地.md
+++ b/problems/kamacoder/0044.开发商购买土地.md
@@ -388,3 +388,85 @@ if __name__ == "__main__":
main()
```
+### C
+
+前缀和
+```c
+#include
+#include
+
+int main()
+{
+ int n = 0, m = 0, ret_ver = 0, ret_hor = 0;
+
+ // 读取行和列的值
+ scanf("%d%d", &n, &m);
+ // 动态分配数组a(横)和b(纵)的空间
+ int *a = (int *)malloc(sizeof(int) * n);
+ int *b = (int *)malloc(sizeof(int) * m);
+
+ // 初始化数组a和b
+ for (int i = 0; i < n; i++)
+ {
+ a[i] = 0;
+ }
+ for (int i = 0; i < m; i++)
+ {
+ b[i] = 0;
+ }
+
+ // 读取区块权值并计算每行和每列的总权值
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < m; j++)
+ {
+ int tmp;
+ scanf("%d", &tmp);
+ a[i] += tmp;
+ b[j] += tmp;
+ }
+ }
+
+ // 计算每列以及每行的前缀和
+ for (int i = 1; i < n; i++)
+ {
+ a[i] += a[i - 1];
+ }
+ for (int i = 1; i < m; i++)
+ {
+ b[i] += b[i - 1];
+ }
+
+ // 初始化ret_ver和ret_hor为最大可能值
+ ret_hor = a[n - 1];
+ ret_ver = b[m - 1];
+
+ // 计算按行划分的最小差异
+ int ret2 = 0;
+ while (ret2 < n)
+ {
+ ret_hor = (ret_hor > abs(a[n - 1] - 2 * a[ret2])) ? abs(a[n - 1] - 2 * a[ret2]) : ret_hor;
+ // 原理同列,但更高级
+ ret2++;
+ }
+ // 计算按列划分的最小差异
+ int ret1 = 0;
+ while (ret1 < m)
+ {
+ if (ret_ver > abs(b[m - 1] - 2 * b[ret1]))
+ {
+ ret_ver = abs(b[m - 1] - 2 * b[ret1]);
+ }
+ ret1++;
+ }
+
+ // 输出最小差异
+ printf("%d\n", (ret_ver <= ret_hor) ? ret_ver : ret_hor);
+
+ // 释放分配的内存
+ free(a);
+ free(b);
+ return 0;
+}
+
+```
diff --git a/problems/kamacoder/0053.寻宝-Kruskal.md b/problems/kamacoder/0053.寻宝-Kruskal.md
index fb816fb1..cb24fd17 100644
--- a/problems/kamacoder/0053.寻宝-Kruskal.md
+++ b/problems/kamacoder/0053.寻宝-Kruskal.md
@@ -562,4 +562,145 @@ if __name__ == "__main__":
### Dart
### C
+并查集方法一
+```c
+#include
+#include
+// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val
+struct Edge
+{
+ int vex1, vex2, val;
+};
+
+// 冒泡排序函数,用于按边的权重val不减序排序边数组
+void bubblesort(struct Edge *a, int numsize)
+{
+ for (int i = 0; i < numsize - 1; ++i)
+ {
+
+ for (int j = 0; j < numsize - i - 1; ++j)
+ {
+ if (a[j].val > a[j + 1].val)
+ {
+ struct Edge temp = a[j];
+ a[j] = a[j + 1];
+ a[j + 1] = temp;
+ }
+ }
+ }
+}
+
+int main()
+{
+ int v, e;
+ int v1, v2, val;
+ int ret = 0;
+
+ scanf("%d%d", &v, &e);
+ struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e);
+ int *conne_gra = (int *)malloc(sizeof(int) * (v + 1));
+
+ // 初始化连通图数组,每个顶点初始时只与自己相连通
+ for (int i = 0; i <= v; ++i)
+ {
+ conne_gra[i] = i;
+ }
+
+ // 读取所有边的信息并存储到edg(存储所有边的)数组中
+ for (int i = 0; i < e; ++i)
+ {
+ scanf("%d%d%d", &v1, &v2, &val);
+ edg[i].vex1 = v1;
+ edg[i].vex2 = v2;
+ edg[i].val = val;
+ }
+ bubblesort(edg, e); // 调用冒泡排序函数对边进行排序
+
+ // 遍历所有边,执行Kruskal算法来找到最小生成树
+ for (int i = 0; i < e; ++i)
+ {
+ if (conne_gra[edg[i].vex1] != conne_gra[edg[i].vex2])
+ { // 如果当前边的两个顶点不在同一个连通分量中
+ int tmp1 = conne_gra[edg[i].vex1], tmp2 = conne_gra[edg[i].vex2];
+ for (int k = 1; k <= v; ++k)
+ { // 将所有属于tmp2的顶点合并到tmp1的连通分量中
+ if (conne_gra[k] == tmp2)
+ conne_gra[k] = tmp1;
+ }
+ ret += edg[i].val; // 将当前边的权重加到最小生成树的权重中
+ }
+ }
+ printf("%d", ret);
+ return 0;
+}
+
+```
+并查集方法二
+```c
+#include
+#include
+
+// 定义边结构体,包含两个顶点vex1和vex2以及它们之间的权重val (略,同上)
+// 冒泡排序函数,用于按边的权重val不减序排序边数组(略,同上)
+
+// 并查集的查找操作
+int find(int m, int *father)
+{ // 如果当前节点是其自身的父节点,则直接返回该节点
+ // 否则递归查找其父节点的根,并将当前节点直接连接到根节点
+ return (m == father[m]) ? m : (father[m] = find(father[m], father)); // 路径压缩
+}
+
+// 并查集的加入集合
+void Union(int m, int n, int *father)
+{
+ int x = find(m, father);
+ int y = find(n, father);
+ if (x == y)
+ return; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
+ father[y] = x;
+}
+
+int main()
+{
+ int v, e;
+ int v1, v2, val;
+ int ret = 0;
+
+ scanf("%d%d", &v, &e);
+ struct Edge *edg = (struct Edge *)malloc(sizeof(struct Edge) * e);
+ int *conne_gra = (int *)malloc(sizeof(int) * (v + 1));
+
+ // 初始化连通图数组,每个顶点初始时只与自己相连通
+ for (int i = 0; i <= v; ++i)
+ {
+ conne_gra[i] = i;
+ }
+ // 读取所有边的信息并存储到edg(存储所有边的)数组中
+ for (int i = 0; i < e; ++i)
+ {
+ scanf("%d%d%d", &v1, &v2, &val);
+ edg[i].vex1 = v1;
+ edg[i].vex2 = v2;
+ edg[i].val = val;
+ }
+
+ bubblesort(edg, e); // 调用冒泡排序函数对边进行排序
+
+ // Kruskal算法的实现,通过边数组构建最小生成树
+ int j = 0, count = 0;
+ while (v > 1)
+ {
+ if (find(edg[j].vex1, conne_gra) != find(edg[j].vex2, conne_gra))
+ {
+ ret += edg[j].val; // 将当前边的权重加到最小生成树的权重中
+ Union(edg[j].vex1, edg[j].vex2, conne_gra);
+ v--;
+ }
+ j++;
+ }
+ printf("%d", ret);
+ return 0;
+}
+
+```
diff --git a/problems/kamacoder/0058.区间和.md b/problems/kamacoder/0058.区间和.md
index f5ce08dc..23e7189a 100644
--- a/problems/kamacoder/0058.区间和.md
+++ b/problems/kamacoder/0058.区间和.md
@@ -263,3 +263,97 @@ if __name__ == "__main__":
main()
```
+
+
+### JavaScript
+
+``` JavaScript
+
+function prefixSum() {
+ const readline = require('readline');
+
+ const rl = readline.createInterface({
+ input: process.stdin,
+ output: process.stdout
+ });
+
+ let inputLines = [];
+ rl.on('line', (line) => {
+ inputLines.push(line.trim());
+ });
+
+ rl.on('close', () => {
+ // 读取项数 n
+ const n = parseInt(inputLines[0]);
+
+ // 使用前缀和,复杂度控制在 O(1)
+ let sum = new Array(n);
+ sum[0] = parseInt(inputLines[1]);
+
+ // 计算前缀和数组
+ for (let i = 1; i < n; i++) {
+ let value = parseInt(inputLines[i + 1]);
+ sum[i] = sum[i - 1] + value;
+ }
+
+ // 处理区间和查询
+ for (let i = n + 1; i < inputLines.length; i++) {
+ let [left, right] = inputLines[i].split(' ').map(Number);
+
+ if (left === 0) {
+ console.log(sum[right]);
+ } else {
+ console.log(sum[right] - sum[left - 1]);
+ }
+ }
+ });
+}
+
+
+```
+
+
+
+### C
+
+```C
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ int num;
+ // 读取数组长度
+ scanf("%d", &num);
+
+ // 使用动态内存分配而不是静态数组,以适应不同的输入大小
+ int *a = (int *)malloc((num + 1) * sizeof(int));
+
+ // 初始化前缀和数组的第一个元素为0
+ a[0] = 0;
+
+ // 读取数组元素并计算前缀和
+ for (int i = 1; i <= num; i++)
+ {
+ int mm;
+ scanf("%d", &mm);
+ // 累加前缀和
+ a[i] = a[i - 1] + mm;
+ }
+
+ int m, n;
+ // 循环读取区间并计算区间和,直到输入结束
+ // scanf()返回成功匹配和赋值的个数,到达文件末尾则返回 EOF
+ while (scanf("%d%d", &m, &n) == 2)
+ {
+ // 输出区间和,注意区间是左闭右开,因此a[n+1]是包含n的元素的前缀和
+ printf("%d\n", a[n+1] - a[m]);
+ }
+
+ // 释放之前分配的内存
+ free(a);
+ return 0;
+}
+
+```
+
diff --git a/problems/kamacoder/0094.城市间货物运输I-SPFA.md b/problems/kamacoder/0094.城市间货物运输I-SPFA.md
index ce383919..b3f42bf8 100644
--- a/problems/kamacoder/0094.城市间货物运输I-SPFA.md
+++ b/problems/kamacoder/0094.城市间货物运输I-SPFA.md
@@ -425,7 +425,39 @@ public class Main {
```
### Python
+```Python
+import collections
+def main():
+ n, m = map(int, input().strip().split())
+ edges = [[] for _ in range(n + 1)]
+ for _ in range(m):
+ src, dest, weight = map(int, input().strip().split())
+ edges[src].append([dest, weight])
+
+ minDist = [float("inf")] * (n + 1)
+ minDist[1] = 0
+ que = collections.deque([1])
+ visited = [False] * (n + 1)
+ visited[1] = True
+
+ while que:
+ cur = que.popleft()
+ visited[cur] = False
+ for dest, weight in edges[cur]:
+ if minDist[cur] != float("inf") and minDist[cur] + weight < minDist[dest]:
+ minDist[dest] = minDist[cur] + weight
+ if visited[dest] == False:
+ que.append(dest)
+ visited[dest] = True
+
+ if minDist[-1] == float("inf"):
+ return "unconnected"
+ return minDist[-1]
+
+if __name__ == "__main__":
+ print(main())
+```
### Go
### Rust
diff --git a/problems/kamacoder/0094.城市间货物运输I.md b/problems/kamacoder/0094.城市间货物运输I.md
index 45ca1313..3737fe01 100644
--- a/problems/kamacoder/0094.城市间货物运输I.md
+++ b/problems/kamacoder/0094.城市间货物运输I.md
@@ -451,6 +451,33 @@ public class Main {
```
### Python
+```Python
+def main():
+ n, m = map(int, input().strip().split())
+ edges = []
+ for _ in range(m):
+ src, dest, weight = map(int, input().strip().split())
+ edges.append([src, dest, weight])
+
+ minDist = [float("inf")] * (n + 1)
+ minDist[1] = 0 # 起点处距离为0
+
+ for i in range(1, n):
+ updated = False
+ for src, dest, weight in edges:
+ if minDist[src] != float("inf") and minDist[src] + weight < minDist[dest]:
+ minDist[dest] = minDist[src] + weight
+ updated = True
+ if not updated: # 若边不再更新,即停止回圈
+ break
+
+ if minDist[-1] == float("inf"): # 返还终点权重
+ return "unconnected"
+ return minDist[-1]
+
+if __name__ == "__main__":
+ print(main())
+```
### Go
diff --git a/problems/kamacoder/0099.岛屿的数量广搜.md b/problems/kamacoder/0099.岛屿的数量广搜.md
index 9fca9a04..30475753 100644
--- a/problems/kamacoder/0099.岛屿的数量广搜.md
+++ b/problems/kamacoder/0099.岛屿的数量广搜.md
@@ -191,10 +191,57 @@ int main() {
### Java
```java
+import java.util.*;
+public class Main {
+ public static int[][] dir = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};//下右上左逆时针遍历
+ public static void bfs(int[][] grid, boolean[][] visited, int x, int y) {
+ Queue queue = new LinkedList();//定义坐标队列,没有现成的pair类,在下面自定义了
+ queue.add(new pair(x, y));
+ visited[x][y] = true;//遇到入队直接标记为优先,
+ // 否则出队时才标记的话会导致重复访问,比如下方节点会在右下顺序的时候被第二次访问入队
+ while (!queue.isEmpty()) {
+ int curX = queue.peek().first;
+ int curY = queue.poll().second;//当前横纵坐标
+ for (int i = 0; i < 4; i++) {
+ //顺时针遍历新节点next,下面记录坐标
+ int nextX = curX + dir[i][0];
+ int nextY = curY + dir[i][1];
+ if (nextX < 0 || nextX >= grid.length || nextY < 0 || nextY >= grid[0].length) {
+ continue;
+ }//去除越界部分
+ if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {
+ queue.add(new pair(nextX, nextY));
+ visited[nextX][nextY] = true;//逻辑同上
+ }
+ }
+ }
+ }
-
+ 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];
+ boolean[][] visited = new boolean[m][n];
+ int ans = 0;
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ grid[i][j] = sc.nextInt();
+ }
+ }
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (!visited[i][j] && grid[i][j] == 1) {
+ ans++;
+ bfs(grid, visited, i, j);
+ }
+ }
+ }
+ System.out.println(ans);
+ }
+}
```
diff --git a/problems/kamacoder/0099.岛屿的数量深搜.md b/problems/kamacoder/0099.岛屿的数量深搜.md
index b257ca9a..6ac7ba3b 100644
--- a/problems/kamacoder/0099.岛屿的数量深搜.md
+++ b/problems/kamacoder/0099.岛屿的数量深搜.md
@@ -182,7 +182,52 @@ int main() {
## 其他语言版本
### Java
+```java
+import java.util.Scanner;
+public class Main {
+ public static int[][] dir ={{0,1},{1,0},{-1,0},{0,-1}};
+ public static void dfs(boolean[][] visited,int x,int y ,int [][]grid)
+ {
+ for (int i = 0; i < 4; i++) {
+ int nextX=x+dir[i][0];
+ int nextY=y+dir[i][1];
+ if(nextY<0||nextX<0||nextX>= grid.length||nextY>=grid[0].length)
+ continue;
+ if(!visited[nextX][nextY]&&grid[nextX][nextY]==1)
+ {
+ visited[nextX][nextY]=true;
+ dfs(visited,nextX,nextY,grid);
+ }
+ }
+ }
+ 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();
+ }
+ }
+ boolean[][]visited =new boolean[m][n];
+ int ans = 0;
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if(!visited[i][j]&&grid[i][j]==1)
+ {
+ ans++;
+ visited[i][j]=true;
+ dfs(visited,i,j,grid);
+ }
+ }
+ }
+ System.out.println(ans);
+ }
+}
+
+```
### Python
版本一
diff --git a/problems/kamacoder/0105.有向图的完全可达性.md b/problems/kamacoder/0105.有向图的完全可达性.md
index cd880a83..838b0212 100644
--- a/problems/kamacoder/0105.有向图的完全可达性.md
+++ b/problems/kamacoder/0105.有向图的完全可达性.md
@@ -289,6 +289,69 @@ int main() {
### Java
+```java
+
+import java.util.*;
+
+public class Main {
+ public static List> adjList = new ArrayList<>();
+
+ public static void dfs(boolean[] visited, int key) {
+ if (visited[key]) {
+ return;
+ }
+ visited[key] = true;
+ List nextKeys = adjList.get(key);
+ for (int nextKey : nextKeys) {
+ dfs(visited, nextKey);
+ }
+ }
+
+ public static void bfs(boolean[] visited, int key) {
+ Queue queue = new LinkedList();
+ queue.add(key);
+ visited[key] = true;
+ while (!queue.isEmpty()) {
+ int curKey = queue.poll();
+ List list = adjList.get(curKey);
+ for (int nextKey : list) {
+ if (!visited[nextKey]) {
+ queue.add(nextKey);
+ visited[nextKey] = true;
+ }
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ Scanner sc = new Scanner(System.in);
+ int vertices_num = sc.nextInt();
+ int line_num = sc.nextInt();
+ for (int i = 0; i < vertices_num; i++) {
+ adjList.add(new LinkedList<>());
+ }//Initialization
+ for (int i = 0; i < line_num; i++) {
+ int s = sc.nextInt();
+ int t = sc.nextInt();
+ adjList.get(s - 1).add(t - 1);
+ }//构造邻接表
+ boolean[] visited = new boolean[vertices_num];
+ dfs(visited, 0);
+// bfs(visited, 0);
+
+ for (int i = 0; i < vertices_num; i++) {
+ if (!visited[i]) {
+ System.out.println(-1);
+ return;
+ }
+ }
+ System.out.println(1);
+ }
+}
+
+```
+
+
### Python
BFS算法
```Python
@@ -327,8 +390,103 @@ if __name__ == "__main__":
```
+``` python
+
+def dfs(graph, key, visited):
+ for neighbor in graph[key]:
+ if not visited[neighbor]: # Check if the next node is not visited
+ visited[neighbor] = True
+ dfs(graph, neighbor, visited)
+
+def main():
+ import sys
+ input = sys.stdin.read
+ data = input().split()
+
+ n = int(data[0])
+ m = int(data[1])
+
+ graph = [[] for _ in range(n + 1)]
+ index = 2
+ for _ in range(m):
+ s = int(data[index])
+ t = int(data[index + 1])
+ graph[s].append(t)
+ index += 2
+
+ visited = [False] * (n + 1)
+ visited[1] = True # Process node 1 beforehand
+ dfs(graph, 1, visited)
+
+ for i in range(1, n + 1):
+ if not visited[i]:
+ print(-1)
+ return
+
+ print(1)
+
+if __name__ == "__main__":
+ main()
+
+
+```
+
### Go
+```go
+
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+)
+
+func dfs(graph [][]int, key int, visited []bool) {
+ visited[key] = true
+ for _, neighbor := range graph[key] {
+ if !visited[neighbor] {
+ dfs(graph, neighbor, visited)
+ }
+ }
+}
+
+func main() {
+ scanner := bufio.NewScanner(os.Stdin)
+ scanner.Scan()
+ var n, m int
+ fmt.Sscanf(scanner.Text(), "%d %d", &n, &m)
+
+ graph := make([][]int, n+1)
+ for i := 0; i <= n; i++ {
+ graph[i] = make([]int, 0)
+ }
+
+ for i := 0; i < m; i++ {
+ scanner.Scan()
+ var s, t int
+ fmt.Sscanf(scanner.Text(), "%d %d", &s, &t)
+ graph[s] = append(graph[s], t)
+ }
+
+ visited := make([]bool, n+1)
+
+ dfs(graph, 1, visited)
+
+ for i := 1; i <= n; i++ {
+ if !visited[i] {
+ fmt.Println(-1)
+ return
+ }
+ }
+ fmt.Println(1)
+}
+
+
+```
+
+
### Rust
### Javascript
diff --git a/problems/kamacoder/0106.岛屿的周长.md b/problems/kamacoder/0106.岛屿的周长.md
index 6f3462c5..235d9445 100644
--- a/problems/kamacoder/0106.岛屿的周长.md
+++ b/problems/kamacoder/0106.岛屿的周长.md
@@ -216,8 +216,131 @@ public class Main {
### Python
+```python
+
+def main():
+ import sys
+ input = sys.stdin.read
+ data = input().split()
+
+ # 读取 n 和 m
+ n = int(data[0])
+ m = int(data[1])
+
+ # 初始化 grid
+ grid = []
+ index = 2
+ for i in range(n):
+ grid.append([int(data[index + j]) for j in range(m)])
+ index += m
+
+ sum_land = 0 # 陆地数量
+ cover = 0 # 相邻数量
+
+ for i in range(n):
+ for j in range(m):
+ if grid[i][j] == 1:
+ sum_land += 1
+ # 统计上边相邻陆地
+ if i - 1 >= 0 and grid[i - 1][j] == 1:
+ cover += 1
+ # 统计左边相邻陆地
+ if j - 1 >= 0 and grid[i][j - 1] == 1:
+ cover += 1
+ # 不统计下边和右边,避免重复计算
+
+ result = sum_land * 4 - cover * 2
+ print(result)
+
+if __name__ == "__main__":
+ main()
+
+
+```
+
### Go
+```go
+
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func main() {
+ scanner := bufio.NewScanner(os.Stdin)
+ scanner.Scan()
+ line := scanner.Text()
+
+ n, m := parseInput(line)
+
+ // 初始化 grid
+ grid := make([][]int, n)
+ for i := range grid {
+ grid[i] = make([]int, m)
+ }
+
+ // 读入 grid 数据
+ for i := 0; i < n; i++ {
+ scanner.Scan()
+ line := scanner.Text()
+ values := parseLine(line, m)
+ for j := 0; j < m; j++ {
+ grid[i][j] = values[j]
+ }
+ }
+
+ sum := 0 // 陆地数量
+ cover := 0 // 相邻数量
+
+ for i := 0; i < n; i++ {
+ for j := 0; j < m; j++ {
+ if grid[i][j] == 1 {
+ sum++ // 统计总的陆地数量
+
+ // 统计上边相邻陆地
+ if i-1 >= 0 && grid[i-1][j] == 1 {
+ cover++
+ }
+ // 统计左边相邻陆地
+ if j-1 >= 0 && grid[i][j-1] == 1 {
+ cover++
+ }
+ // 为什么没统计下边和右边? 因为避免重复计算
+ }
+ }
+ }
+
+ fmt.Println(sum*4 - cover*2)
+}
+
+// parseInput 解析 n 和 m
+func parseInput(line string) (int, int) {
+ parts := strings.Split(line, " ")
+ n, _ := strconv.Atoi(parts[0])
+ m, _ := strconv.Atoi(parts[1])
+ return n, m
+}
+
+// parseLine 解析一行中的多个值
+func parseLine(line string, count int) []int {
+ parts := strings.Split(line, " ")
+ values := make([]int, count)
+ for i := 0; i < count; i++ {
+ values[i], _ = strconv.Atoi(parts[i])
+ }
+ return values
+}
+
+
+```
+
+
### Rust
### Javascript
diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md
index b665070c..b5862bb5 100644
--- a/problems/背包理论基础01背包-2.md
+++ b/problems/背包理论基础01背包-2.md
@@ -298,23 +298,18 @@ public class Main {
```python
n, bagweight = map(int, input().split())
-
weight = list(map(int, input().split()))
value = list(map(int, input().split()))
-dp = [[0] * (bagweight + 1) for _ in range(n)]
+dp = [0] * (bagweight + 1) # 创建一个动态规划数组dp,初始值为0
-for j in range(weight[0], bagweight + 1):
- dp[0][j] = value[0]
+dp[0] = 0 # 初始化dp[0] = 0,背包容量为0,价值最大为0
-for i in range(1, n):
- for j in range(bagweight + 1):
- 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])
+for i in range(n): # 应该先遍历物品,如果遍历背包容量放在上一层,那么每个dp[j]就只会放入一个物品
+ for j in range(bagweight, weight[i]-1, -1): # 倒序遍历背包容量是为了保证物品i只被放入一次
+ dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
-print(dp[n - 1][bagweight])
+print(dp[bagweight])
```
### Go