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

This commit is contained in:
programmercarl
2024-07-26 11:35:46 +08:00
18 changed files with 1709 additions and 106 deletions

View File

@@ -339,7 +339,7 @@ int main() {
}
}
```
```
## 空间优化
@@ -426,6 +426,68 @@ floyd算法的时间复杂度相对较高适合 稠密图且源点较多的
### Python
基于三维数组的Floyd
```python
if __name__ == '__main__':
max_int = 10005 # 设置最大路径因为边最大距离为10^4
n, m = map(int, input().split())
grid = [[[max_int] * (n+1) for _ in range(n+1)] for _ in range(n+1)] # 初始化三维dp数组
for _ in range(m):
p1, p2, w = map(int, input().split())
grid[p1][p2][0] = w
grid[p2][p1][0] = w
# 开始floyd
for k in range(1, n+1):
for i in range(1, n+1):
for j in range(1, n+1):
grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1] + grid[k][j][k-1])
# 输出结果
z = int(input())
for _ in range(z):
start, end = map(int, input().split())
if grid[start][end][n] == max_int:
print(-1)
else:
print(grid[start][end][n])
```
基于二维数组的Floyd
```python
if __name__ == '__main__':
max_int = 10005 # 设置最大路径因为边最大距离为10^4
n, m = map(int, input().split())
grid = [[max_int]*(n+1) for _ in range(n+1)] # 初始化二维dp数组
for _ in range(m):
p1, p2, val = map(int, input().split())
grid[p1][p2] = val
grid[p2][p1] = val
# 开始floyd
for k in range(1, n+1):
for i in range(1, n+1):
for j in range(1, n+1):
grid[i][j] = min(grid[i][j], grid[i][k] + grid[k][j])
# 输出结果
z = int(input())
for _ in range(z):
start, end = map(int, input().split())
if grid[start][end] == max_int:
print(-1)
else:
print(grid[start][end])
```
### Go
### Rust

View File

@@ -75,7 +75,7 @@
## 插曲
-------------
-------------
本题和力扣 [797.所有可能的路径](https://leetcode.cn/problems/all-paths-from-source-to-target/description/) 是一样的,录友了解深度优先搜索之后,这道题目就是模板题,是送分题。
@@ -476,7 +476,7 @@ public class Main {
}
}
}
```
```
邻接表写法
```java
@@ -565,7 +565,7 @@ def main():
if __name__ == "__main__":
main()
```
```
邻接表写法
``` python
@@ -609,6 +609,145 @@ if __name__ == "__main__":
### Javascript
#### 邻接矩阵写法
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async ()=>(await iter.next()).value;
let graph;
let N, M;
// 收集符合条件的路径
let result = [];
// 1节点到终点的路径
let path = [];
// 创建邻接矩阵,初始化邻接矩阵
async function initGraph(){
let line;
line = await readline();
[N, M] = line.split(' ').map(i => parseInt(i))
graph = new Array(N + 1).fill(0).map(() => new Array(N + 1).fill(0))
while(M--){
line = await readline()
const strArr = line ? line.split(' ').map(i => parseInt(i)) : undefined
strArr ? graph[strArr[0]][strArr[1]] = 1 : null
}
};
// 深度搜索
function dfs(graph, x, n){
// 当前遍历节点为x 到达节点为n
if(x == n){
result.push([...path])
return
}
for(let i = 1 ; i <= n ; i++){
if(graph[x][i] == 1){
path.push(i)
dfs(graph, i, n )
path.pop(i)
}
}
};
(async function(){
// 创建邻接矩阵,初始化邻接矩阵
await initGraph();
// 从节点1开始深度搜索
path.push(1);
// 深度搜索
dfs(graph, 1, N );
// 输出
if(result.length > 0){
result.forEach(i => {
console.log(i.join(' '))
})
}else{
console.log(-1)
}
})();
```
#### 邻接表写法
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph;
let N, M;
// 收集符合条件的路径
let result = [];
// 1节点到终点的路径
let path = [];
// 创建邻接表,初始化邻接表
async function initGraph() {
let line;
line = await readline();
[N, M] = line.split(' ').map(i => parseInt(i))
graph = new Array(N + 1).fill(0).map(() => new Array())
while (line = await readline()) {
const strArr = line.split(' ').map(i => parseInt(i))
strArr ? graph[strArr[0]].push(strArr[1]) : null
}
};
// 深度搜索
async function dfs(graph, x, n) {
// 当前遍历节点为x 到达节点为n
if (x == n) {
result.push([...path])
return
}
graph[x].forEach(i => {
path.push(i)
dfs(graph, i, n)
path.pop(i)
})
};
(async function () {
// 创建邻接表,初始化邻接表
await initGraph();
// 从节点1开始深度搜索
path.push(1);
// 深度搜索
dfs(graph, 1, N);
// 输出
if (result.length > 0) {
result.forEach(i => {
console.log(i.join(' '))
})
} else {
console.log(-1)
}
})();
```
### TypeScript
### PhP
@@ -629,4 +768,3 @@ if __name__ == "__main__":

View File

@@ -190,24 +190,309 @@ int main() {
### Java
```java
import java.util.Scanner;
public class Main {
static int[][] dir = { {0, 1}, {1, 0}, {-1, 0}, {0, -1} }; // 四个方向
public static void dfs(int[][] grid, boolean[][] visited, int x, int y) {
for (int i = 0; i < 4; i++) {
int nextx = x + dir[i][0];
int nexty = y + dir[i][1];
if (nextx < 0 || nextx >= grid.length || nexty < 0 || nexty >= grid[0].length) continue; // 越界了,直接跳过
if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) { // 没有访问过的 同时 是陆地的
visited[nextx][nexty] = true;
dfs(grid, visited, nextx, nexty);
}
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] grid = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
grid[i][j] = scanner.nextInt();
}
}
boolean[][] visited = new boolean[n][m];
int result = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (!visited[i][j] && grid[i][j] == 1) {
visited[i][j] = true;
result++; // 遇到没访问过的陆地,+1
dfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true
}
}
}
System.out.println(result);
}
}
```
### Python
```python
def dfs(grid, visited, x, y):
dir = [(0, 1), (1, 0), (-1, 0), (0, -1)] # 四个方向
for d in dir:
nextx, nexty = x + d[0], y + d[1]
if 0 <= nextx < len(grid) and 0 <= nexty < len(grid[0]):
if not visited[nextx][nexty] and grid[nextx][nexty] == 1: # 没有访问过的 同时 是陆地的
visited[nextx][nexty] = True
dfs(grid, visited, nextx, nexty)
def main():
n, m = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(n)]
visited = [[False] * m for _ in range(n)]
result = 0
for i in range(n):
for j in range(m):
if not visited[i][j] and grid[i][j] == 1:
visited[i][j] = True
result += 1 # 遇到没访问过的陆地,+1
dfs(grid, visited, i, j) # 将与其链接的陆地都标记上 True
print(result)
if __name__ == "__main__":
main()
```
### Go
```go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
var dir = [4][2]int{{0, 1}, {1, 0}, {-1, 0}, {0, -1}} // 四个方向
func dfs(grid [][]int, visited [][]bool, x, y int) {
for i := 0; i < 4; i++ {
nextx := x + dir[i][0]
nexty := y + dir[i][1]
if nextx < 0 || nextx >= len(grid) || nexty < 0 || nexty >= len(grid[0]) {
continue // 越界了,直接跳过
}
if !visited[nextx][nexty] && grid[nextx][nexty] == 1 { // 没有访问过的 同时 是陆地的
visited[nextx][nexty] = true
dfs(grid, visited, nextx, nexty)
}
}
}
func main() {
reader := bufio.NewReader(os.Stdin)
var n, m int
fmt.Scanf("%d %d", &n, &m)
grid := make([][]int, n)
for i := 0; i < n; i++ {
grid[i] = make([]int, m)
line, _ := reader.ReadString('\n')
line = strings.TrimSpace(line)
elements := strings.Split(line, " ")
for j := 0; j < m; j++ {
grid[i][j], _ = strconv.Atoi(elements[j])
}
}
visited := make([][]bool, n)
for i := 0; i < n; i++ {
visited[i] = make([]bool, m)
}
result := 0
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if !visited[i][j] && grid[i][j] == 1 {
visited[i][j] = true
result++ // 遇到没访问过的陆地,+1
dfs(grid, visited, i, j) // 将与其链接的陆地都标记上 true
}
}
}
fmt.Println(result)
}
```
### Rust
### Javascript
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph
let N, M
let visited
let result = 0
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]]
// 读取输入,初始化地图
const initGraph = async () => {
let line = await readline();
[N, M] = line.split(' ').map(Number);
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
visited = new Array(N).fill(false).map(() => new Array(M).fill(false))
for (let i = 0; i < N; i++) {
line = await readline()
line = line.split(' ').map(Number)
for (let j = 0; j < M; j++) {
graph[i][j] = line[j]
}
}
}
/**
* @description: 从(x, y)开始广度优先遍历
* @param {*} graph 地图
* @param {*} visited 访问过的节点
* @param {*} x 开始搜索节点的下标
* @param {*} y 开始搜索节点的下标
* @return {*}
*/
const bfs = (graph, visited, x, y) => {
let queue = []
queue.push([x, y])
visited[x][y] = true //只要加入队列就立刻标记为访问过
while (queue.length) {
let [x, y] = queue.shift()
for (let i = 0; i < 4; i++) {
let nextx = x + dir[i][0]
let nexty = y + dir[i][1]
if(nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
if(!visited[nextx][nexty] && graph[nextx][nexty] === 1){
queue.push([nextx, nexty])
visited[nextx][nexty] = true
}
}
}
}
(async function () {
// 读取输入,初始化地图
await initGraph()
// 统计岛屿数
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (!visited[i][j] && graph[i][j] === 1) {
// 遇到没访问过的陆地,+1
result++
// 广度优先遍历,将相邻陆地标记为已访问
bfs(graph, visited, i, j)
}
}
}
console.log(result);
})()
```
### TypeScript
### PhP
```PHP
<?php
function dfs($grid, &$visited, $x, $y) {
$dir = [[0, 1], [1, 0], [-1, 0], [0, -1]]; // 四个方向
foreach ($dir as $d) {
$nextx = $x + $d[0];
$nexty = $y + $d[1];
if ($nextx < 0 || $nextx >= count($grid) || $nexty < 0 || $nexty >= count($grid[0])) {
continue; // 越界了,直接跳过
}
if (!$visited[$nextx][$nexty] && $grid[$nextx][$nexty] == 1) { // 没有访问过的 同时 是陆地的
$visited[$nextx][$nexty] = true;
dfs($grid, $visited, $nextx, $nexty);
}
}
}
function main() {
fscanf(STDIN, "%d %d", $n, $m);
$grid = [];
for ($i = 0; $i < $n; $i++) {
$grid[$i] = array_map('intval', explode(' ', trim(fgets(STDIN))));
}
$visited = array_fill(0, $n, array_fill(0, $m, false));
$result = 0;
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $m; $j++) {
if (!$visited[$i][$j] && $grid[$i][$j] == 1) {
$visited[$i][$j] = true;
$result++; // 遇到没访问过的陆地,+1
dfs($grid, $visited, $i, $j); // 将与其链接的陆地都标记上 true
}
}
}
echo $result . PHP_EOL;
}
main();
?>
```
### Swift
### Scala
### C#
### Dart
### C

View File

@@ -185,12 +185,181 @@ int main() {
### Python
版本一
```python
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:上、右、下、左
def dfs(grid, visited, x, y):
"""
对一块陆地进行深度优先遍历并标记
"""
for i, j in direction:
next_x = x + i
next_y = y + j
# 下标越界,跳过
if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
continue
# 未访问的陆地,标记并调用深度优先搜索
if not visited[next_x][next_y] and grid[next_x][next_y] == 1:
visited[next_x][next_y] = True
dfs(grid, visited, next_x, next_y)
if __name__ == '__main__':
# 版本一
n, m = map(int, input().split())
# 邻接矩阵
grid = []
for i in range(n):
grid.append(list(map(int, input().split())))
# 访问表
visited = [[False] * m for _ in range(n)]
res = 0
for i in range(n):
for j in range(m):
# 判断如果当前节点是陆地res+1并标记访问该节点使用深度搜索标记相邻陆地。
if grid[i][j] == 1 and not visited[i][j]:
res += 1
visited[i][j] = True
dfs(grid, visited, i, j)
print(res)
```
版本二
```python
direction = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向:上、右、下、左
def dfs(grid, visited, x, y):
"""
对一块陆地进行深度优先遍历并标记
"""
# 与版本一的差别,在调用前增加判断终止条件
if visited[x][y] or grid[x][y] == 0:
return
visited[x][y] = True
for i, j in direction:
next_x = x + i
next_y = y + j
# 下标越界,跳过
if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
continue
# 由于判断条件放在了方法首部此处直接调用dfs方法
dfs(grid, visited, next_x, next_y)
if __name__ == '__main__':
# 版本二
n, m = map(int, input().split())
# 邻接矩阵
grid = []
for i in range(n):
grid.append(list(map(int, input().split())))
# 访问表
visited = [[False] * m for _ in range(n)]
res = 0
for i in range(n):
for j in range(m):
# 判断如果当前节点是陆地res+1并标记访问该节点使用深度搜索标记相邻陆地。
if grid[i][j] == 1 and not visited[i][j]:
res += 1
dfs(grid, visited, i, j)
print(res)
```
### Go
### Rust
### Javascript
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph
let N, M
let visited
let result = 0
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]]
// 读取输入,初始化地图
const initGraph = async () => {
let line = await readline();
[N, M] = line.split(' ').map(Number);
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
visited = new Array(N).fill(false).map(() => new Array(M).fill(false))
for (let i = 0; i < N; i++) {
line = await readline()
line = line.split(' ').map(Number)
for (let j = 0; j < M; j++) {
graph[i][j] = line[j]
}
}
}
/**
* @description: 从节点x,y开始深度优先遍历
* @param {*} graph 是地图,也就是一个二维数组
* @param {*} visited 标记访问过的节点,不要重复访问
* @param {*} x 表示开始搜索节点的下标
* @param {*} y 表示开始搜索节点的下标
* @return {*}
*/
const dfs = (graph, visited, x, y) => {
for (let i = 0; i < 4; i++) {
const nextx = x + dir[i][0]
const nexty = y + dir[i][1]
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
if (!visited[nextx][nexty] && graph[nextx][nexty] === 1) {
visited[nextx][nexty] = true
dfs(graph, visited, nextx, nexty)
}
}
}
(async function () {
// 读取输入,初始化地图
await initGraph()
// 统计岛屿数
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (!visited[i][j] && graph[i][j] === 1) {
// 标记已访问
visited[i][j] = true
// 遇到没访问过的陆地,+1
result++
// 深度优先遍历,将相邻陆地标记为已访问
dfs(graph, visited, i, j)
}
}
}
console.log(result);
})()
```
### TypeScript
### PhP

View File

@@ -226,12 +226,196 @@ public:
### Python
DFS
```python
# 四个方向
position = [[0, 1], [1, 0], [0, -1], [-1, 0]]
count = 0
def dfs(grid, visited, x, y):
"""
深度优先搜索,对一整块陆地进行标记
"""
global count # 定义全局变量便于传递count值
for i, j in position:
cur_x = x + i
cur_y = y + j
# 下标越界,跳过
if cur_x < 0 or cur_x >= len(grid) or cur_y < 0 or cur_y >= len(grid[0]):
continue
if not visited[cur_x][cur_y] and grid[cur_x][cur_y] == 1:
visited[cur_x][cur_y] = True
count += 1
dfs(grid, visited, cur_x, cur_y)
n, m = map(int, input().split())
# 邻接矩阵
grid = []
for i in range(n):
grid.append(list(map(int, input().split())))
# 访问表
visited = [[False] * m for _ in range(n)]
result = 0 # 记录最终结果
for i in range(n):
for j in range(m):
if grid[i][j] == 1 and not visited[i][j]:
count = 1
visited[i][j] = True
dfs(grid, visited, i, j)
result = max(count, result)
print(result)
```
BFS
```python
from collections import deque
position = [[0, 1], [1, 0], [0, -1], [-1, 0]] # 四个方向
count = 0
def bfs(grid, visited, x, y):
"""
广度优先搜索对陆地进行标记
"""
global count # 声明全局变量
que = deque()
que.append([x, y])
while que:
cur_x, cur_y = que.popleft()
for i, j in position:
next_x = cur_x + i
next_y = cur_y + j
# 下标越界,跳过
if next_x < 0 or next_x >= len(grid) or next_y < 0 or next_y >= len(grid[0]):
continue
if grid[next_x][next_y] == 1 and not visited[next_x][next_y]:
visited[next_x][next_y] = True
count += 1
que.append([next_x, next_y])
n, m = map(int, input().split())
# 邻接矩阵
grid = []
for i in range(n):
grid.append(list(map(int, input().split())))
visited = [[False] * m for _ in range(n)] # 访问表
result = 0 # 记录最终结果
for i in range(n):
for j in range(m):
if grid[i][j] == 1 and not visited[i][j]:
count = 1
visited[i][j] = True
bfs(grid, visited, i, j)
res = max(result, count)
print(result)
```
### Go
### Rust
### Javascript
```javascript
// 广搜版
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph // 地图
let N, M // 地图大小
let visited // 访问过的节点
let result = 0 // 最大岛屿面积
let count = 0 // 岛屿内节点数
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
// 读取输入,初始化地图
const initGraph = async () => {
let line = await readline();
[N, M] = line.split(' ').map(Number);
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
visited = new Array(N).fill(false).map(() => new Array(M).fill(false))
for (let i = 0; i < N; i++) {
line = await readline()
line = line.split(' ').map(Number)
for (let j = 0; j < M; j++) {
graph[i][j] = line[j]
}
}
}
/**
* @description: 从(x, y)开始广度优先遍历
* @param {*} graph 地图
* @param {*} visited 访问过的节点
* @param {*} x 开始搜索节点的下标
* @param {*} y 开始搜索节点的下标
* @return {*}
*/
const bfs = (graph, visited, x, y) => {
let queue = []
queue.push([x, y])
count++
visited[x][y] = true //只要加入队列就立刻标记为访问过
while (queue.length) {
let [xx, yy] = queue.shift()
for (let i = 0; i < 4; i++) {
let nextx = xx + dir[i][0]
let nexty = yy + dir[i][1]
if(nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
if(!visited[nextx][nexty] && graph[nextx][nexty] === 1){
queue.push([nextx, nexty])
count++
visited[nextx][nexty] = true
}
}
}
}
(async function () {
// 读取输入,初始化地图
await initGraph()
// 统计最大岛屿面积
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (!visited[i][j] && graph[i][j] === 1) { //遇到没有访问过的陆地
// 重新计算面积
count = 0
// 广度优先遍历,统计岛屿内节点数,并将岛屿标记为已访问
bfs(graph, visited, i, j)
// 更新最大岛屿面积
result = Math.max(result, count)
}
}
}
console.log(result);
})()
```
### TypeScript
### PhP

View File

@@ -242,6 +242,173 @@ print(count)
### Javascript
#### 深搜版
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph // 地图
let N, M // 地图大小
let count = 0 // 孤岛的总面积
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
// 读取输入,初始化地图
const initGraph = async () => {
let line = await readline();
[N, M] = line.split(' ').map(Number);
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
for (let i = 0; i < N; i++) {
line = await readline()
line = line.split(' ').map(Number)
for (let j = 0; j < M; j++) {
graph[i][j] = line[j]
}
}
}
/**
* @description: 从xy开始深度优先遍历地图
* @param {*} graph 地图
* @param {*} x 开始搜索节点的下标
* @param {*} y 开始搜索节点的下标
* @return {*}
*/
const dfs = (graph, x, y) => {
if(graph[x][y] === 0) return
graph[x][y] = 0 // 标记为海洋
for (let i = 0; i < 4; i++) {
let nextx = x + dir[i][0]
let nexty = y + dir[i][1]
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
dfs(graph, nextx, nexty)
}
}
(async function () {
// 读取输入,初始化地图
await initGraph()
// 遍历地图左右两边
for (let i = 0; i < N; i++) {
if (graph[i][0] === 1) dfs(graph, i, 0)
if (graph[i][M - 1] === 1) dfs(graph, i, M - 1)
}
// 遍历地图上下两边
for (let j = 0; j < M; j++) {
if (graph[0][j] === 1) dfs(graph, 0, j)
if (graph[N - 1][j] === 1) dfs(graph, N - 1, j)
}
count = 0
// 统计孤岛的总面积
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (graph[i][j] === 1) count++
}
}
console.log(count);
})()
```
#### 广搜版
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph // 地图
let N, M // 地图大小
let count = 0 // 孤岛的总面积
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
// 读取输入,初始化地图
const initGraph = async () => {
let line = await readline();
[N, M] = line.split(' ').map(Number);
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
for (let i = 0; i < N; i++) {
line = await readline()
line = line.split(' ').map(Number)
for (let j = 0; j < M; j++) {
graph[i][j] = line[j]
}
}
}
/**
* @description: 从xy开始广度优先遍历地图
* @param {*} graph 地图
* @param {*} x 开始搜索节点的下标
* @param {*} y 开始搜索节点的下标
* @return {*}
*/
const bfs = (graph, x, y) => {
let queue = []
queue.push([x, y])
graph[x][y] = 0 // 只要加入队列,立刻标记
while (queue.length) {
let [xx, yy] = queue.shift()
for (let i = 0; i < 4; i++) {
let nextx = xx + dir[i][0]
let nexty = yy + dir[i][1]
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
if (graph[nextx][nexty] === 1) {
queue.push([nextx, nexty])
graph[nextx][nexty] = 0 // 只要加入队列,立刻标记
}
}
}
}
(async function () {
// 读取输入,初始化地图
await initGraph()
// 遍历地图左右两边
for (let i = 0; i < N; i++) {
if (graph[i][0] === 1) bfs(graph, i, 0)
if (graph[i][M - 1] === 1) bfs(graph, i, M - 1)
}
// 遍历地图上下两边
for (let j = 0; j < M; j++) {
if (graph[0][j] === 1) bfs(graph, 0, j)
if (graph[N - 1][j] === 1) bfs(graph, N - 1, j)
}
count = 0
// 统计孤岛的总面积
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (graph[i][j] === 1) count++
}
}
console.log(count);
})()
```
### TypeScript
### PhP

View File

@@ -146,6 +146,171 @@ int main() {
### Javascript
#### 深搜版
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph // 地图
let N, M // 地图大小
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
// 读取输入,初始化地图
const initGraph = async () => {
let line = await readline();
[N, M] = line.split(' ').map(Number);
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
for (let i = 0; i < N; i++) {
line = await readline()
line = line.split(' ').map(Number)
for (let j = 0; j < M; j++) {
graph[i][j] = line[j]
}
}
}
/**
* @description: 从xy开始深度优先遍历地图
* @param {*} graph 地图
* @param {*} x 开始搜索节点的下标
* @param {*} y 开始搜索节点的下标
* @return {*}
*/
const dfs = (graph, x, y) => {
if (graph[x][y] !== 1) return
graph[x][y] = 2 // 标记为非孤岛陆地
for (let i = 0; i < 4; i++) {
let nextx = x + dir[i][0]
let nexty = y + dir[i][1]
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
dfs(graph, nextx, nexty)
}
}
(async function () {
// 读取输入,初始化地图
await initGraph()
// 遍历地图左右两边
for (let i = 0; i < N; i++) {
if (graph[i][0] === 1) dfs(graph, i, 0)
if (graph[i][M - 1] === 1) dfs(graph, i, M - 1)
}
// 遍历地图上下两边
for (let j = 0; j < M; j++) {
if (graph[0][j] === 1) dfs(graph, 0, j)
if (graph[N - 1][j] === 1) dfs(graph, N - 1, j)
}
// 遍历地图将孤岛沉没即将陆地1标记为0将非孤岛陆地2标记为1
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (graph[i][j] === 1) graph[i][j] = 0
else if (graph[i][j] === 2) graph[i][j] = 1
}
console.log(graph[i].join(' '));
}
})()
```
#### 广搜版
```javascript
const r1 = require('readline').createInterface({ input: process.stdin });
// 创建readline接口
let iter = r1[Symbol.asyncIterator]();
// 创建异步迭代器
const readline = async () => (await iter.next()).value;
let graph // 地图
let N, M // 地图大小
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
// 读取输入,初始化地图
const initGraph = async () => {
let line = await readline();
[N, M] = line.split(' ').map(Number);
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
for (let i = 0; i < N; i++) {
line = await readline()
line = line.split(' ').map(Number)
for (let j = 0; j < M; j++) {
graph[i][j] = line[j]
}
}
}
/**
* @description: 从xy开始广度优先遍历地图
* @param {*} graph 地图
* @param {*} x 开始搜索节点的下标
* @param {*} y 开始搜索节点的下标
* @return {*}
*/
const bfs = (graph, x, y) => {
let queue = []
queue.push([x, y])
graph[x][y] = 2 // 标记为非孤岛陆地
while (queue.length) {
let [xx, yy] = queue.shift()
for (let i = 0; i < 4; i++) {
let nextx = xx + dir[i][0]
let nexty = yy + dir[i][1]
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
if (graph[nextx][nexty] === 1) bfs(graph, nextx, nexty)
}
}
}
(async function () {
// 读取输入,初始化地图
await initGraph()
// 遍历地图左右两边
for (let i = 0; i < N; i++) {
if (graph[i][0] === 1) bfs(graph, i, 0)
if (graph[i][M - 1] === 1) bfs(graph, i, M - 1)
}
// 遍历地图上下两边
for (let j = 0; j < M; j++) {
if (graph[0][j] === 1) bfs(graph, 0, j)
if (graph[N - 1][j] === 1) bfs(graph, N - 1, j)
}
// 遍历地图将孤岛沉没即将陆地1标记为0将非孤岛陆地2标记为1
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (graph[i][j] === 1) graph[i][j] = 0
else if (graph[i][j] === 2) graph[i][j] = 1
}
console.log(graph[i].join(' '));
}
})()
```
### TypeScript
### PhP

View File

@@ -281,6 +281,78 @@ for (int j = 0; j < m; j++) {
## 其他语言版本
### Java
```Java
public class Main {
// 采用 DFS 进行搜索
public static void dfs(int[][] heights, int x, int y, boolean[][] visited, int preH) {
// 遇到边界或者访问过的点,直接返回
if (x < 0 || x >= heights.length || y < 0 || y >= heights[0].length || visited[x][y]) return;
// 不满足水流入条件的直接返回
if (heights[x][y] < preH) return;
// 满足条件设置为true表示可以从边界到达此位置
visited[x][y] = true;
// 向下一层继续搜索
dfs(heights, x + 1, y, visited, heights[x][y]);
dfs(heights, x - 1, y, visited, heights[x][y]);
dfs(heights, x, y + 1, visited, heights[x][y]);
dfs(heights, x, y - 1, visited, heights[x][y]);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] heights = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
heights[i][j] = sc.nextInt();
}
}
// 初始化两个二位boolean数组代表两个边界
boolean[][] pacific = new boolean[m][n];
boolean[][] atlantic = new boolean[m][n];
// 从左右边界出发进行DFS
for (int i = 0; i < m; i++) {
dfs(heights, i, 0, pacific, Integer.MIN_VALUE);
dfs(heights, i, n - 1, atlantic, Integer.MIN_VALUE);
}
// 从上下边界出发进行DFS
for (int j = 0; j < n; j++) {
dfs(heights, 0, j, pacific, Integer.MIN_VALUE);
dfs(heights, m - 1, j, atlantic, Integer.MIN_VALUE);
}
// 当两个边界二维数组在某个位置都为true时符合题目要求
List<List<Integer>> res = new ArrayList<>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) {
res.add(Arrays.asList(i, j));
}
}
}
// 打印结果
for (List<Integer> list : res) {
for (int k = 0; k < list.size(); k++) {
if (k == 0) {
System.out.print(list.get(k) + " ");
} else {
System.out.print(list.get(k));
}
}
System.out.println();
}
}
}
```
### Python

View File

@@ -258,6 +258,111 @@ int main() {
## 其他语言版本
### Java
```Java
public class Main {
// 该方法采用 DFS
// 定义全局变量
// 记录每次每个岛屿的面积
static int count;
// 对每个岛屿进行标记
static int mark;
// 定义二维数组表示四个方位
static int[][] dirs = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
// DFS 进行搜索,将每个岛屿标记为不同的数字
public static void dfs(int[][] grid, int x, int y, boolean[][] visited) {
// 当遇到边界直接return
if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length) return;
// 遇到已经访问过的或者遇到海水,直接返回
if (visited[x][y] || grid[x][y] == 0) return;
visited[x][y] = true;
count++;
grid[x][y] = mark;
// 继续向下层搜索
dfs(grid, x, y + 1, visited);
dfs(grid, x, y - 1, visited);
dfs(grid, x + 1, y, visited);
dfs(grid, x - 1, y, visited);
}
public static void main (String[] args) {
// 接收输入
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc.nextInt();
int[][] grid = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
grid[i][j] = sc.nextInt();
}
}
// 初始化mark变量从2开始区别于0水1岛屿
mark = 2;
// 定义二位boolean数组记录该位置是否被访问
boolean[][] visited = new boolean[m][n];
// 定义一个HashMap记录某片岛屿的标记号和面积
HashMap<Integer, Integer> getSize = new HashMap<>();
// 定义一个HashSet用来判断某一位置水四周是否存在不同标记编号的岛屿
HashSet<Integer> set = new HashSet<>();
// 定义一个boolean变量看看DFS之后是否全是岛屿
boolean isAllIsland = true;
// 遍历二维数组进行DFS搜索标记每片岛屿的编号记录对应的面积
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) isAllIsland = false;
if (grid[i][j] == 1) {
count = 0;
dfs(grid, i, j, visited);
getSize.put(mark, count);
mark++;
}
}
}
int result = 0;
if (isAllIsland) result = m * n;
// 对标记完的grid继续遍历判断每个水位置四周是否有岛屿并记录下四周不同相邻岛屿面积之和
// 每次计算完一个水位置周围可能存在的岛屿面积之和更新下result变量
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) {
set.clear();
// 当前水位置变更为岛屿所以初始化为1
int curSize = 1;
for (int[] dir : dirs) {
int curRow = i + dir[0];
int curCol = j + dir[1];
if (curRow < 0 || curRow >= m || curCol < 0 || curCol >= n) continue;
int curMark = grid[curRow][curCol];
// 如果当前相邻的岛屿已经遍历过或者HashMap中不存在这个编号继续搜索
if (set.contains(curMark) || !getSize.containsKey(curMark)) continue;
set.add(curMark);
curSize += getSize.get(curMark);
}
result = Math.max(result, curSize);
}
}
}
// 打印结果
System.out.println(result);
}
}
```
### Python

View File

@@ -66,7 +66,7 @@
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20240524120105.png)
录友的下边空格出界了,则说明找到一条边。
陆地的下边空格出界了,则说明找到一条边。
C++代码如下:(详细注释)
@@ -157,7 +157,62 @@ int main() {
## 其他语言版本
### Java
### Java
```Java
import java.util.*;
public class Main {
// 每次遍历到1探索其周围4个方向并记录周长最终合计
// 声明全局变量dirs表示4个方向
static int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
// 统计每单个1的周长
static int count;
// 探索其周围4个方向并记录周长
public static void helper(int[][] grid, int x, int y) {
for (int[] dir : dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
// 遇到边界或者水,周长加一
if (nx < 0 || nx >= grid.length || ny < 0 || ny >= grid[0].length
|| grid[nx][ny] == 0) {
count++;
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 接收输入
int M = sc.nextInt();
int N = sc.nextInt();
int[][] grid = new int[M][N];
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
grid[i][j] = sc.nextInt();
}
}
int result = 0; // 总周长
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if (grid[i][j] == 1) {
count = 0;
helper(grid, i, j);
// 更新总周长
result += count;
}
}
}
// 打印结果
System.out.println(result);
}
}
```
### Python

View File

@@ -153,6 +153,68 @@ int main() {
## 其他语言版本
### Java
```Java
public class Main {
// BFS方法
public static int ladderLength(String beginWord, String endWord, List<String> wordList) {
// 使用set作为查询容器效率更高
HashSet<String> set = new HashSet<>(wordList);
// 声明一个queue存储每次变更一个字符得到的且存在于容器中的新字符串
Queue<String> queue = new LinkedList<>();
// 声明一个hashMap存储遍历到的字符串以及所走过的路径path
HashMap<String, Integer> visitMap = new HashMap<>();
queue.offer(beginWord);
visitMap.put(beginWord, 1);
while (!queue.isEmpty()) {
String curWord = queue.poll();
int path = visitMap.get(curWord);
for (int i = 0; i < curWord.length(); i++) {
char[] ch = curWord.toCharArray();
// 每个位置尝试26个字母
for (char k = 'a'; k <= 'z'; k++) {
ch[i] = k;
String newWord = new String(ch);
if (newWord.equals(endWord)) return path + 1;
// 如果这个新字符串存在于容器且之前未被访问到
if (set.contains(newWord) && !visitMap.containsKey(newWord)) {
visitMap.put(newWord, path + 1);
queue.offer(newWord);
}
}
}
}
return 0;
}
public static void main (String[] args) {
/* code */
// 接收输入
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
sc.nextLine();
String[] strs = sc.nextLine().split(" ");
List<String> wordList = new ArrayList<>();
for (int i = 0; i < N; i++) {
wordList.add(sc.nextLine());
}
// wordList.add(strs[1]);
// 打印结果
int result = ladderLength(strs[0], strs[1], wordList);
System.out.println(result);
}
}
```
### Python