mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@ -794,6 +794,60 @@ func rebuild(inorder []int, postorder []int, rootIdx int, l, r int) *TreeNode {
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func buildTree(inorder []int, postorder []int) *TreeNode {
|
||||
if len(postorder) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 后序遍历数组最后一个元素,就是当前的中间节点
|
||||
rootValue := postorder[len(postorder)-1]
|
||||
root := &TreeNode{Val:rootValue}
|
||||
|
||||
// 叶子结点
|
||||
if len(postorder) == 1 {
|
||||
return root
|
||||
}
|
||||
|
||||
// 找到中序遍历的切割点
|
||||
var delimiterIndex int
|
||||
for delimiterIndex = 0; delimiterIndex < len(inorder); delimiterIndex++ {
|
||||
if inorder[delimiterIndex] == rootValue {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 切割中序数组
|
||||
// 左闭右开区间:[0, delimiterIndex)
|
||||
leftInorder := inorder[:delimiterIndex]
|
||||
// [delimiterIndex + 1, end)
|
||||
rightInorder := inorder[delimiterIndex+1:]
|
||||
|
||||
// postorder 舍弃末尾元素
|
||||
postorder = postorder[:len(postorder)-1]
|
||||
|
||||
// 切割后序数组
|
||||
// 依然左闭右开,注意这里使用了左中序数组大小作为切割点
|
||||
// [0, len(leftInorder))
|
||||
leftPostorder := postorder[:len(leftInorder)]
|
||||
// [len(leftInorder), end)
|
||||
rightPostorder := postorder[len(leftInorder):]
|
||||
|
||||
root.Left = buildTree(leftInorder, leftPostorder)
|
||||
root.Right = buildTree(rightInorder, rightPostorder)
|
||||
|
||||
return root
|
||||
}
|
||||
```
|
||||
|
||||
105 从前序与中序遍历序列构造二叉树
|
||||
|
||||
```go
|
||||
@ -829,6 +883,60 @@ func build(pre []int, in []int, root int, l, r int) *TreeNode {
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func buildTree(preorder []int, inorder []int) *TreeNode {
|
||||
if len(preorder) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 前序遍历数组第一个元素,就是当前的中间节点
|
||||
rootValue := preorder[0]
|
||||
root := &TreeNode{Val:rootValue}
|
||||
|
||||
// 叶子结点
|
||||
if len(preorder) == 1 {
|
||||
return root
|
||||
}
|
||||
|
||||
// 找到中序遍历的切割点
|
||||
var delimiterIndex int
|
||||
for delimiterIndex = 0; delimiterIndex < len(inorder); delimiterIndex++ {
|
||||
if inorder[delimiterIndex] == rootValue {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 切割中序数组
|
||||
// 左闭右开区间:[0, delimiterIndex)
|
||||
leftInorder := inorder[:delimiterIndex]
|
||||
// [delimiterIndex + 1, end)
|
||||
rightInorder := inorder[delimiterIndex+1:]
|
||||
|
||||
// preorder 舍弃首位元素
|
||||
preorder = preorder[1:]
|
||||
|
||||
// 切割前序数组
|
||||
// 依然左闭右开,注意这里使用了左中序数组大小作为切割点
|
||||
// [0, len(leftInorder))
|
||||
leftPreorder := preorder[:len(leftInorder)]
|
||||
// [len(leftInorder), end)
|
||||
rightPreorder := preorder[len(leftInorder):]
|
||||
|
||||
root.Left = buildTree(leftPreorder, leftInorder)
|
||||
root.Right = buildTree(rightPreorder, rightInorder)
|
||||
|
||||
return root
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### JavaScript
|
||||
|
||||
|
@ -466,7 +466,7 @@ function maxProfit(prices: number[]): number {
|
||||
};
|
||||
```
|
||||
|
||||
> 动态规划
|
||||
> 动态规划:版本一
|
||||
|
||||
```typescript
|
||||
function maxProfit(prices: number[]): number {
|
||||
@ -487,6 +487,26 @@ function maxProfit(prices: number[]): number {
|
||||
};
|
||||
```
|
||||
|
||||
> 动态规划:版本二
|
||||
|
||||
```typescript
|
||||
// dp[i][0] 表示第i天持有股票所得最多现金
|
||||
// dp[i][1] 表示第i天不持有股票所得最多现金
|
||||
function maxProfit(prices: number[]): number {
|
||||
const dp:number[][] = Array(2).fill(0).map(item => Array(2));
|
||||
dp[0][0] = -prices[0];
|
||||
dp[0][1] = 0;
|
||||
|
||||
for (let i = 1; i < prices.length; i++) {
|
||||
dp[i % 2][0] = Math.max(dp[(i - 1) % 2][0], -prices[i]);
|
||||
dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]);
|
||||
}
|
||||
|
||||
// 返回不持有股票的最大现金
|
||||
return dp[(prices.length-1) % 2][1];
|
||||
};
|
||||
```
|
||||
|
||||
### C#:
|
||||
|
||||
> 贪心法
|
||||
|
@ -310,39 +310,35 @@ public:
|
||||
### Java
|
||||
```Java
|
||||
class Solution {
|
||||
List<List<String>> lists = new ArrayList<>();
|
||||
Deque<String> deque = new LinkedList<>();
|
||||
|
||||
//保持前几题一贯的格式, initialization
|
||||
List<List<String>> res = new ArrayList<>();
|
||||
List<String> cur = new ArrayList<>();
|
||||
public List<List<String>> partition(String s) {
|
||||
backTracking(s, 0);
|
||||
return lists;
|
||||
backtracking(s, 0, new StringBuilder());
|
||||
return res;
|
||||
}
|
||||
|
||||
private void backTracking(String s, int startIndex) {
|
||||
//如果起始位置大于s的大小,说明找到了一组分割方案
|
||||
if (startIndex >= s.length()) {
|
||||
lists.add(new ArrayList(deque));
|
||||
private void backtracking(String s, int start, StringBuilder sb){
|
||||
//因为是起始位置一个一个加的,所以结束时start一定等于s.length,因为进入backtracking时一定末尾也是回文,所以cur是满足条件的
|
||||
if (start == s.length()){
|
||||
//注意创建一个新的copy
|
||||
res.add(new ArrayList<>(cur));
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < s.length(); i++) {
|
||||
//如果是回文子串,则记录
|
||||
if (isPalindrome(s, startIndex, i)) {
|
||||
String str = s.substring(startIndex, i + 1);
|
||||
deque.addLast(str);
|
||||
} else {
|
||||
continue;
|
||||
//像前两题一样从前往后搜索,如果发现回文,进入backtracking,起始位置后移一位,循环结束照例移除cur的末位
|
||||
for (int i = start; i < s.length(); i++){
|
||||
sb.append(s.charAt(i));
|
||||
if (check(sb)){
|
||||
cur.add(sb.toString());
|
||||
backtracking(s, i + 1, new StringBuilder());
|
||||
cur.remove(cur.size() -1 );
|
||||
}
|
||||
//起始位置后移,保证不重复
|
||||
backTracking(s, i + 1);
|
||||
deque.removeLast();
|
||||
}
|
||||
}
|
||||
//判断是否是回文串
|
||||
private boolean isPalindrome(String s, int startIndex, int end) {
|
||||
for (int i = startIndex, j = end; i < j; i++, j--) {
|
||||
if (s.charAt(i) != s.charAt(j)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//helper method, 检查是否是回文
|
||||
private boolean check(StringBuilder sb){
|
||||
for (int i = 0; i < sb.length()/ 2; i++){
|
||||
if (sb.charAt(i) != sb.charAt(sb.length() - 1 - i)){return false;}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -359,6 +359,26 @@ func max(a, b int) int {
|
||||
|
||||
### Javascript:
|
||||
|
||||
> 不同的状态定义 感觉更容易理解些
|
||||
```javascript
|
||||
function maxProfit(prices) {
|
||||
// 第i天状态 持股 卖出 非冷冻期(不持股) 处于冷冻期
|
||||
const dp = new Array(prices.length).fill(0).map(() => [0, 0, 0, 0]);
|
||||
dp[0][0] = -prices[0];
|
||||
for (let i = 1; i < prices.length; i++) {
|
||||
// 持股
|
||||
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][2] - prices[i]);
|
||||
// 卖出
|
||||
dp[i][1] = dp[i - 1][0] + prices[i];
|
||||
// 非冷冻期(不持股)
|
||||
dp[i][2] = Math.max(dp[i - 1][2], dp[i - 1][1]);
|
||||
// 冷冻期(上一天卖出)
|
||||
dp[i][3] = dp[i - 1][1];
|
||||
}
|
||||
return Math.max(...dp.pop());
|
||||
};
|
||||
```
|
||||
|
||||
```javascript
|
||||
const maxProfit = (prices) => {
|
||||
if(prices.length < 2) {
|
||||
|
@ -511,7 +511,7 @@ object Solution {
|
||||
|
||||
```
|
||||
|
||||
###Ruby
|
||||
### Ruby:
|
||||
```ruby
|
||||
def intersection(nums1, nums2)
|
||||
hash = {}
|
||||
|
@ -87,7 +87,7 @@
|
||||
回归本题,整个插入过程如下:
|
||||
|
||||
排序完的people:
|
||||
[[7,0], [7,1], [6,1], [5,0], [5,2],[4,4]]
|
||||
[[7,0], [7,1], [6,1], [5,0], [5,2], [4,4]]
|
||||
|
||||
插入的过程:
|
||||
* 插入[7,0]:[[7,0]]
|
||||
|
@ -168,109 +168,103 @@ private:
|
||||
### C:
|
||||
|
||||
```C
|
||||
typedef struct MyLinkedList {
|
||||
int val;
|
||||
struct MyLinkedList* next;
|
||||
}MyLinkedList;
|
||||
typedef struct Node {
|
||||
int val;
|
||||
struct Node* next;
|
||||
} Node;
|
||||
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
Node* data;
|
||||
} MyLinkedList;
|
||||
|
||||
/** Initialize your data structure here. */
|
||||
|
||||
MyLinkedList* myLinkedListCreate() {
|
||||
//这个题必须用虚拟头指针,参数都是一级指针,头节点确定后没法改指向了!!!
|
||||
MyLinkedList* head = (MyLinkedList *)malloc(sizeof (MyLinkedList));
|
||||
head->next = NULL;
|
||||
return head;
|
||||
MyLinkedList* obj = (MyLinkedList*)malloc(sizeof(MyLinkedList));
|
||||
Node* head = (Node*)malloc(sizeof(Node));
|
||||
head->next = (void*)0;
|
||||
obj->data = head;
|
||||
obj->size = 0;
|
||||
return obj;
|
||||
}
|
||||
|
||||
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
|
||||
int myLinkedListGet(MyLinkedList* obj, int index) {
|
||||
MyLinkedList *cur = obj->next;
|
||||
for (int i = 0; cur != NULL; i++){
|
||||
if (i == index){
|
||||
return cur->val;
|
||||
}
|
||||
else{
|
||||
cur = cur->next;
|
||||
}
|
||||
if (index < 0 || index >= obj->size) return -1;
|
||||
|
||||
Node* cur = obj->data;
|
||||
while (index-- >= 0) {
|
||||
cur = cur->next;
|
||||
}
|
||||
return -1;
|
||||
|
||||
return cur->val;
|
||||
}
|
||||
|
||||
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
|
||||
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
|
||||
MyLinkedList *nhead = (MyLinkedList *)malloc(sizeof (MyLinkedList));
|
||||
nhead->val = val;
|
||||
nhead->next = obj->next;
|
||||
obj->next = nhead;
|
||||
Node* node = (Node*)malloc(sizeof(Node));
|
||||
node->val = val;
|
||||
|
||||
node->next = obj->data->next;
|
||||
obj->data->next = node;
|
||||
obj->size++;
|
||||
}
|
||||
|
||||
/** Append a node of value val to the last element of the linked list. */
|
||||
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
|
||||
MyLinkedList *cur = obj;
|
||||
while(cur->next != NULL){
|
||||
Node* cur = obj->data;
|
||||
while (cur->next != ((void*)0)) {
|
||||
cur = cur->next;
|
||||
}
|
||||
MyLinkedList *ntail = (MyLinkedList *)malloc(sizeof (MyLinkedList));
|
||||
ntail->val = val;
|
||||
ntail->next = NULL;
|
||||
cur->next = ntail;
|
||||
|
||||
Node* tail = (Node*)malloc(sizeof(Node));
|
||||
tail->val = val;
|
||||
tail->next = (void*)0;
|
||||
cur->next = tail;
|
||||
obj->size++;
|
||||
}
|
||||
|
||||
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
|
||||
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
|
||||
if (index == 0){
|
||||
myLinkedListAddAtHead(obj, val);
|
||||
return;
|
||||
}
|
||||
MyLinkedList *cur = obj->next;
|
||||
for (int i = 1 ;cur != NULL; i++){
|
||||
if (i == index){
|
||||
MyLinkedList* newnode = (MyLinkedList *)malloc(sizeof (MyLinkedList));
|
||||
newnode->val = val;
|
||||
newnode->next = cur->next;
|
||||
cur->next = newnode;
|
||||
return;
|
||||
}
|
||||
else{
|
||||
cur = cur->next;
|
||||
}
|
||||
if (index > obj->size) return;
|
||||
|
||||
Node* cur = obj->data;
|
||||
while (index-- > 0) {
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
Node* node = (Node*)malloc(sizeof(Node));
|
||||
node->val = val;
|
||||
node->next = cur->next;
|
||||
cur->next = node;
|
||||
obj->size++;
|
||||
}
|
||||
|
||||
/** Delete the index-th node in the linked list, if the index is valid. */
|
||||
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
|
||||
if (index == 0){
|
||||
MyLinkedList *tmp = obj->next;
|
||||
if (tmp != NULL){
|
||||
obj->next = tmp->next;
|
||||
free(tmp);
|
||||
}
|
||||
return;
|
||||
if (index < 0 || index >= obj->size) return;
|
||||
|
||||
Node* cur = obj->data;
|
||||
while (index-- > 0) {
|
||||
cur = cur->next;
|
||||
}
|
||||
MyLinkedList *cur = obj->next;
|
||||
for (int i = 1 ;cur != NULL && cur->next != NULL; i++){
|
||||
if (i == index){
|
||||
MyLinkedList *tmp = cur->next;
|
||||
if (tmp != NULL) {
|
||||
cur->next = tmp->next;
|
||||
free(tmp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else{
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Node* temp = cur->next;
|
||||
cur->next = temp->next;
|
||||
free(temp);
|
||||
obj->size--;
|
||||
}
|
||||
|
||||
void myLinkedListFree(MyLinkedList* obj) {
|
||||
while(obj != NULL){
|
||||
MyLinkedList *tmp = obj;
|
||||
obj = obj->next;
|
||||
free(tmp);
|
||||
}
|
||||
Node* tmp = obj->data;
|
||||
while (tmp != NULL) {
|
||||
Node* n = tmp;
|
||||
tmp = tmp->next;
|
||||
free(n);
|
||||
}
|
||||
free(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1569,3 +1563,4 @@ public class MyLinkedList
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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__":
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -242,6 +242,173 @@ print(count)
|
||||
|
||||
### Javascript
|
||||
|
||||
#### 深搜版
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
let graph // 地图
|
||||
let N, M // 地图大小
|
||||
let count = 0 // 孤岛的总面积
|
||||
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
|
||||
|
||||
|
||||
// 读取输入,初始化地图
|
||||
const initGraph = async () => {
|
||||
let line = await readline();
|
||||
[N, M] = line.split(' ').map(Number);
|
||||
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
for (let j = 0; j < M; j++) {
|
||||
graph[i][j] = line[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description: 从(x,y)开始深度优先遍历地图
|
||||
* @param {*} graph 地图
|
||||
* @param {*} x 开始搜索节点的下标
|
||||
* @param {*} y 开始搜索节点的下标
|
||||
* @return {*}
|
||||
*/
|
||||
const dfs = (graph, x, y) => {
|
||||
if(graph[x][y] === 0) return
|
||||
graph[x][y] = 0 // 标记为海洋
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let nextx = x + dir[i][0]
|
||||
let nexty = y + dir[i][1]
|
||||
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
|
||||
dfs(graph, nextx, nexty)
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
|
||||
// 读取输入,初始化地图
|
||||
await initGraph()
|
||||
|
||||
// 遍历地图左右两边
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (graph[i][0] === 1) dfs(graph, i, 0)
|
||||
if (graph[i][M - 1] === 1) dfs(graph, i, M - 1)
|
||||
}
|
||||
|
||||
// 遍历地图上下两边
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[0][j] === 1) dfs(graph, 0, j)
|
||||
if (graph[N - 1][j] === 1) dfs(graph, N - 1, j)
|
||||
}
|
||||
|
||||
count = 0
|
||||
// 统计孤岛的总面积
|
||||
for (let i = 0; i < N; i++) {
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[i][j] === 1) count++
|
||||
}
|
||||
}
|
||||
console.log(count);
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 广搜版
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
let graph // 地图
|
||||
let N, M // 地图大小
|
||||
let count = 0 // 孤岛的总面积
|
||||
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
|
||||
|
||||
|
||||
// 读取输入,初始化地图
|
||||
const initGraph = async () => {
|
||||
let line = await readline();
|
||||
[N, M] = line.split(' ').map(Number);
|
||||
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
for (let j = 0; j < M; j++) {
|
||||
graph[i][j] = line[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description: 从(x,y)开始广度优先遍历地图
|
||||
* @param {*} graph 地图
|
||||
* @param {*} x 开始搜索节点的下标
|
||||
* @param {*} y 开始搜索节点的下标
|
||||
* @return {*}
|
||||
*/
|
||||
const bfs = (graph, x, y) => {
|
||||
let queue = []
|
||||
queue.push([x, y])
|
||||
graph[x][y] = 0 // 只要加入队列,立刻标记
|
||||
|
||||
while (queue.length) {
|
||||
let [xx, yy] = queue.shift()
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let nextx = xx + dir[i][0]
|
||||
let nexty = yy + dir[i][1]
|
||||
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
|
||||
if (graph[nextx][nexty] === 1) {
|
||||
queue.push([nextx, nexty])
|
||||
graph[nextx][nexty] = 0 // 只要加入队列,立刻标记
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
(async function () {
|
||||
|
||||
// 读取输入,初始化地图
|
||||
await initGraph()
|
||||
|
||||
// 遍历地图左右两边
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (graph[i][0] === 1) bfs(graph, i, 0)
|
||||
if (graph[i][M - 1] === 1) bfs(graph, i, M - 1)
|
||||
}
|
||||
|
||||
// 遍历地图上下两边
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[0][j] === 1) bfs(graph, 0, j)
|
||||
if (graph[N - 1][j] === 1) bfs(graph, N - 1, j)
|
||||
}
|
||||
|
||||
count = 0
|
||||
// 统计孤岛的总面积
|
||||
for (let i = 0; i < N; i++) {
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[i][j] === 1) count++
|
||||
}
|
||||
}
|
||||
console.log(count);
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -146,6 +146,171 @@ int main() {
|
||||
|
||||
### Javascript
|
||||
|
||||
#### 深搜版
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
let graph // 地图
|
||||
let N, M // 地图大小
|
||||
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
|
||||
|
||||
|
||||
// 读取输入,初始化地图
|
||||
const initGraph = async () => {
|
||||
let line = await readline();
|
||||
[N, M] = line.split(' ').map(Number);
|
||||
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
for (let j = 0; j < M; j++) {
|
||||
graph[i][j] = line[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description: 从(x,y)开始深度优先遍历地图
|
||||
* @param {*} graph 地图
|
||||
* @param {*} x 开始搜索节点的下标
|
||||
* @param {*} y 开始搜索节点的下标
|
||||
* @return {*}
|
||||
*/
|
||||
const dfs = (graph, x, y) => {
|
||||
if (graph[x][y] !== 1) return
|
||||
graph[x][y] = 2 // 标记为非孤岛陆地
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let nextx = x + dir[i][0]
|
||||
let nexty = y + dir[i][1]
|
||||
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
|
||||
dfs(graph, nextx, nexty)
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
|
||||
// 读取输入,初始化地图
|
||||
await initGraph()
|
||||
|
||||
// 遍历地图左右两边
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (graph[i][0] === 1) dfs(graph, i, 0)
|
||||
if (graph[i][M - 1] === 1) dfs(graph, i, M - 1)
|
||||
}
|
||||
|
||||
// 遍历地图上下两边
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[0][j] === 1) dfs(graph, 0, j)
|
||||
if (graph[N - 1][j] === 1) dfs(graph, N - 1, j)
|
||||
}
|
||||
|
||||
|
||||
// 遍历地图,将孤岛沉没,即将陆地1标记为0;将非孤岛陆地2标记为1
|
||||
for (let i = 0; i < N; i++) {
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[i][j] === 1) graph[i][j] = 0
|
||||
else if (graph[i][j] === 2) graph[i][j] = 1
|
||||
}
|
||||
console.log(graph[i].join(' '));
|
||||
}
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 广搜版
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
let graph // 地图
|
||||
let N, M // 地图大小
|
||||
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
|
||||
|
||||
|
||||
// 读取输入,初始化地图
|
||||
const initGraph = async () => {
|
||||
let line = await readline();
|
||||
[N, M] = line.split(' ').map(Number);
|
||||
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
for (let j = 0; j < M; j++) {
|
||||
graph[i][j] = line[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description: 从(x,y)开始广度优先遍历地图
|
||||
* @param {*} graph 地图
|
||||
* @param {*} x 开始搜索节点的下标
|
||||
* @param {*} y 开始搜索节点的下标
|
||||
* @return {*}
|
||||
*/
|
||||
const bfs = (graph, x, y) => {
|
||||
let queue = []
|
||||
queue.push([x, y])
|
||||
graph[x][y] = 2 // 标记为非孤岛陆地
|
||||
|
||||
while (queue.length) {
|
||||
let [xx, yy] = queue.shift()
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let nextx = xx + dir[i][0]
|
||||
let nexty = yy + dir[i][1]
|
||||
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue
|
||||
if (graph[nextx][nexty] === 1) bfs(graph, nextx, nexty)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
|
||||
// 读取输入,初始化地图
|
||||
await initGraph()
|
||||
|
||||
// 遍历地图左右两边
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (graph[i][0] === 1) bfs(graph, i, 0)
|
||||
if (graph[i][M - 1] === 1) bfs(graph, i, M - 1)
|
||||
}
|
||||
|
||||
// 遍历地图上下两边
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[0][j] === 1) bfs(graph, 0, j)
|
||||
if (graph[N - 1][j] === 1) bfs(graph, N - 1, j)
|
||||
}
|
||||
|
||||
|
||||
// 遍历地图,将孤岛沉没,即将陆地1标记为0;将非孤岛陆地2标记为1
|
||||
for (let i = 0; i < N; i++) {
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[i][j] === 1) graph[i][j] = 0
|
||||
else if (graph[i][j] === 2) graph[i][j] = 1
|
||||
}
|
||||
console.log(graph[i].join(' '));
|
||||
}
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
||||
|
||||

|
||||
|
||||
该录友的下边空格出界了,则说明找到一条边。
|
||||
该陆地的下边空格出界了,则说明找到一条边。
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user