Merge branch 'master' of github.com:youngyangyang04/leetcode-master

This commit is contained in:
programmercarl
2024-09-14 11:24:16 +08:00
18 changed files with 966 additions and 42 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -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 {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -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 {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -388,3 +388,85 @@ if __name__ == "__main__":
main()
```
### C
前缀和
```c
#include <stdlib.h>
#include <stdio.h>
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;
}
```

View File

@ -562,4 +562,145 @@ if __name__ == "__main__":
### Dart
### C
并查集方法一
```c
#include <stdio.h>
#include <stdlib.h>
// 定义边结构体包含两个顶点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 <stdio.h>
#include <stdlib.h>
// 定义边结构体包含两个顶点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;
}
```

View File

@ -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 <stdio.h>
#include <stdlib.h>
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;
}
```

View File

@ -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

View File

@ -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

View File

@ -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<pair> queue = new LinkedList<pair>();//定义坐标队列没有现成的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);
}
}
```

View File

@ -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
版本一

View File

@ -289,6 +289,69 @@ int main() {
### Java
```java
import java.util.*;
public class Main {
public static List<List<Integer>> adjList = new ArrayList<>();
public static void dfs(boolean[] visited, int key) {
if (visited[key]) {
return;
}
visited[key] = true;
List<Integer> nextKeys = adjList.get(key);
for (int nextKey : nextKeys) {
dfs(visited, nextKey);
}
}
public static void bfs(boolean[] visited, int key) {
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(key);
visited[key] = true;
while (!queue.isEmpty()) {
int curKey = queue.poll();
List<Integer> 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

View File

@ -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

View File

@ -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