mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
Merge branch 'master' into fix-bug-description
This commit is contained in:
@ -251,8 +251,8 @@ class Solution {
|
||||
|
||||
for (int i = 0; i < nums.length; i++) {
|
||||
|
||||
// nums[i] > target 直接返回, 剪枝操作
|
||||
if (nums[i] > 0 && nums[i] > target) {
|
||||
// nums[i] >= 0 && nums[i] > target 直接返回, 剪枝操作
|
||||
if (nums[i] >= 0 && nums[i] > target) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -262,11 +262,13 @@ class Solution {
|
||||
|
||||
for (int j = i + 1; j < nums.length; j++) {
|
||||
|
||||
|
||||
// nums[i]+nums[j] > target 直接返回, 剪枝操作
|
||||
if (nums[i]+nums[j] > 0 && nums[i]+nums[j] > target) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (j > i + 1 && nums[j - 1] == nums[j]) { // 对nums[j]去重
|
||||
continue;
|
||||
}
|
||||
@ -274,7 +276,7 @@ class Solution {
|
||||
int left = j + 1;
|
||||
int right = nums.length - 1;
|
||||
while (right > left) {
|
||||
// nums[k] + nums[i] + nums[left] + nums[right] > target int会溢出
|
||||
// nums[j] + nums[i] + nums[left] + nums[right] int 可能会溢出,需要转为 long
|
||||
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
|
||||
if (sum > target) {
|
||||
right--;
|
||||
|
@ -310,6 +310,43 @@ class Solution:
|
||||
```
|
||||
### Go
|
||||
|
||||
使用used数组
|
||||
```Go
|
||||
var (
|
||||
result [][]int
|
||||
path []int
|
||||
)
|
||||
|
||||
func subsetsWithDup(nums []int) [][]int {
|
||||
result = make([][]int, 0)
|
||||
path = make([]int, 0)
|
||||
used := make([]bool, len(nums))
|
||||
sort.Ints(nums) // 去重需要排序
|
||||
backtracing(nums, 0, used)
|
||||
return result
|
||||
}
|
||||
|
||||
func backtracing(nums []int, startIndex int, used []bool) {
|
||||
tmp := make([]int, len(path))
|
||||
copy(tmp, path)
|
||||
result = append(result, tmp)
|
||||
for i := startIndex; i < len(nums); i++ {
|
||||
// used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
|
||||
// used[i - 1] == false,说明同一树层candidates[i - 1]使用过
|
||||
// 而我们要对同一树层使用过的元素进行跳过
|
||||
if i > 0 && nums[i] == nums[i-1] && used[i-1] == false {
|
||||
continue
|
||||
}
|
||||
path = append(path, nums[i])
|
||||
used[i] = true
|
||||
backtracing(nums, i + 1, used)
|
||||
path = path[:len(path)-1]
|
||||
used[i] = false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
不使用used数组
|
||||
```Go
|
||||
var (
|
||||
path []int
|
||||
|
@ -169,6 +169,56 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
```Java
|
||||
// 迭代法
|
||||
class Solution {
|
||||
public Node connect(Node root) {
|
||||
if (root == null) {
|
||||
return root;
|
||||
}
|
||||
|
||||
Queue<Node> queue = new LinkedList<>();
|
||||
|
||||
queue.add(root);
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
int size = queue.size();
|
||||
|
||||
// 每层的第一个节点
|
||||
Node cur = queue.poll();
|
||||
if (cur.left != null) {
|
||||
queue.add(cur.left);
|
||||
}
|
||||
if (cur.right != null) {
|
||||
queue.add(cur.right);
|
||||
}
|
||||
|
||||
// 因为已经移除了每层的第一个节点,所以将 0 改为 1
|
||||
while (size-- > 1) {
|
||||
Node next = queue.poll();
|
||||
|
||||
if (next.left != null) {
|
||||
queue.add(next.left);
|
||||
}
|
||||
if (next.right != null) {
|
||||
queue.add(next.right);
|
||||
}
|
||||
|
||||
// 当前节点指向同层的下一个节点
|
||||
cur.next = next;
|
||||
// 更新当前节点
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// 每层的最后一个节点不指向 null 在力扣也能过
|
||||
cur.next = null;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
@ -443,3 +493,4 @@ public class Solution
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -149,7 +149,35 @@ public:
|
||||
* 时间复杂度: O(n)
|
||||
* 空间复杂度: O(1)
|
||||
|
||||
**也可以通过递归的思路解决本题:**
|
||||
|
||||
基础情况:对于空链表,不需要移除元素。
|
||||
|
||||
递归情况:首先检查头节点的值是否为 val,如果是则移除头节点,答案即为在头节点的后续节点上递归的结果;如果头节点的值不为 val,则答案为头节点与在头节点的后续节点上递归得到的新链表拼接的结果。
|
||||
|
||||
```CPP
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* removeElements(ListNode* head, int val) {
|
||||
// 基础情况:空链表
|
||||
if (head == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// 递归处理
|
||||
if (head->val == val) {
|
||||
ListNode* newHead = removeElements(head->next, val);
|
||||
delete head;
|
||||
return newHead;
|
||||
} else {
|
||||
head->next = removeElements(head->next, val);
|
||||
return head;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
* 时间复杂度:O(n)
|
||||
* 空间复杂度:O(n)
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||

|
||||
|
||||
这道题目背后有一个让程序员心酸的故事,听说 Homebrew的作者Max Howell,就是因为没在白板上写出翻转二叉树,最后被Google拒绝了。(真假不做判断,权当一个乐子哈)
|
||||
这道题目背后有一个让程序员心酸的故事,听说 Homebrew的作者Max Howell,就是因为没在白板上写出翻转二叉树,最后被Google拒绝了。(真假不做判断,全当一个乐子哈)
|
||||
|
||||
## 算法公开课
|
||||
|
||||
@ -1033,3 +1033,4 @@ public TreeNode InvertTree(TreeNode root) {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -44,7 +44,7 @@ queue.empty(); // 返回 false
|
||||
|
||||
这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。
|
||||
|
||||
使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。
|
||||
使用栈来模拟队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。
|
||||
|
||||
下面动画模拟以下队列的执行过程:
|
||||
|
||||
|
@ -309,6 +309,8 @@ class Solution:
|
||||
|
||||
```
|
||||
### Go
|
||||
|
||||
动态规划
|
||||
```go
|
||||
func integerBreak(n int) int {
|
||||
/**
|
||||
@ -338,6 +340,28 @@ func max(a, b int) int{
|
||||
}
|
||||
```
|
||||
|
||||
贪心
|
||||
```go
|
||||
func integerBreak(n int) int {
|
||||
if n == 2 {
|
||||
return 1
|
||||
}
|
||||
if n == 3 {
|
||||
return 2
|
||||
}
|
||||
if n == 4 {
|
||||
return 4
|
||||
}
|
||||
result := 1
|
||||
for n > 4 {
|
||||
result *= 3
|
||||
n -= 3
|
||||
}
|
||||
result *= n
|
||||
return result
|
||||
}
|
||||
```
|
||||
|
||||
### Javascript
|
||||
```Javascript
|
||||
var integerBreak = function(n) {
|
||||
|
@ -207,6 +207,7 @@ class Solution:
|
||||
new_list.append(nums[left] ** 2)
|
||||
left += 1
|
||||
return new_list[::-1]
|
||||
```
|
||||
|
||||
### Go:
|
||||
|
||||
@ -539,7 +540,7 @@ public class Solution {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
C# LINQ:
|
||||
```csharp
|
||||
public class Solution {
|
||||
@ -553,3 +554,4 @@ public class Solution {
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
</a>
|
||||
|
||||
|
@ -352,6 +352,77 @@ SPFA(队列优化版Bellman_ford) 在理论上 时间复杂度更胜一筹
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
```Java
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
|
||||
// Define an inner class Edge
|
||||
static class Edge {
|
||||
int from;
|
||||
int to;
|
||||
int val;
|
||||
public Edge(int from, int to, int val) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Input processing
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n = sc.nextInt();
|
||||
int m = sc.nextInt();
|
||||
List<List<Edge>> graph = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i <= n; i++) {
|
||||
graph.add(new ArrayList<>());
|
||||
}
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
int from = sc.nextInt();
|
||||
int to = sc.nextInt();
|
||||
int val = sc.nextInt();
|
||||
graph.get(from).add(new Edge(from, to, val));
|
||||
}
|
||||
|
||||
// Declare the minDist array to record the minimum distance form current node to the original node
|
||||
int[] minDist = new int[n + 1];
|
||||
Arrays.fill(minDist, Integer.MAX_VALUE);
|
||||
minDist[1] = 0;
|
||||
|
||||
// Declare a queue to store the updated nodes instead of traversing all nodes each loop for more efficiency
|
||||
Queue<Integer> queue = new LinkedList<>();
|
||||
queue.offer(1);
|
||||
|
||||
// Declare a boolean array to record if the current node is in the queue to optimise the processing
|
||||
boolean[] isInQueue = new boolean[n + 1];
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
int curNode = queue.poll();
|
||||
isInQueue[curNode] = false; // Represents the current node is not in the queue after being polled
|
||||
for (Edge edge : graph.get(curNode)) {
|
||||
if (minDist[edge.to] > minDist[edge.from] + edge.val) { // Start relaxing the edge
|
||||
minDist[edge.to] = minDist[edge.from] + edge.val;
|
||||
if (!isInQueue[edge.to]) { // Don't add the node if it's already in the queue
|
||||
queue.offer(edge.to);
|
||||
isInQueue[edge.to] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Outcome printing
|
||||
if (minDist[n] == Integer.MAX_VALUE) {
|
||||
System.out.println("unconnected");
|
||||
} else {
|
||||
System.out.println(minDist[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
|
@ -392,6 +392,63 @@ Bellman_ford 是可以计算 负权值的单源最短路算法。
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
```Java
|
||||
public class Main {
|
||||
|
||||
// Define an inner class Edge
|
||||
static class Edge {
|
||||
int from;
|
||||
int to;
|
||||
int val;
|
||||
public Edge(int from, int to, int val) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Input processing
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n = sc.nextInt();
|
||||
int m = sc.nextInt();
|
||||
List<Edge> edges = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
int from = sc.nextInt();
|
||||
int to = sc.nextInt();
|
||||
int val = sc.nextInt();
|
||||
edges.add(new Edge(from, to, val));
|
||||
}
|
||||
|
||||
// Represents the minimum distance from the current node to the original node
|
||||
int[] minDist = new int[n + 1];
|
||||
|
||||
// Initialize the minDist array
|
||||
Arrays.fill(minDist, Integer.MAX_VALUE);
|
||||
minDist[1] = 0;
|
||||
|
||||
// Starts the loop to relax all edges n - 1 times to update minDist array
|
||||
for (int i = 1; i < n; i++) {
|
||||
|
||||
for (Edge edge : edges) {
|
||||
// Updates the minDist array
|
||||
if (minDist[edge.from] != Integer.MAX_VALUE && (minDist[edge.from] + edge.val) < minDist[edge.to]) {
|
||||
minDist[edge.to] = minDist[edge.from] + edge.val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Outcome printing
|
||||
if (minDist[n] == Integer.MAX_VALUE) {
|
||||
System.out.println("unconnected");
|
||||
} else {
|
||||
System.out.println(minDist[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
|
@ -244,6 +244,92 @@ int main() {
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
```Java
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
// 基于Bellman_ford-SPFA方法
|
||||
// Define an inner class Edge
|
||||
static class Edge {
|
||||
int from;
|
||||
int to;
|
||||
int val;
|
||||
public Edge(int from, int to, int val) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Input processing
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n = sc.nextInt();
|
||||
int m = sc.nextInt();
|
||||
List<List<Edge>> graph = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i <= n; i++) {
|
||||
graph.add(new ArrayList<>());
|
||||
}
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
int from = sc.nextInt();
|
||||
int to = sc.nextInt();
|
||||
int val = sc.nextInt();
|
||||
graph.get(from).add(new Edge(from, to, val));
|
||||
}
|
||||
|
||||
// Declare the minDist array to record the minimum distance form current node to the original node
|
||||
int[] minDist = new int[n + 1];
|
||||
Arrays.fill(minDist, Integer.MAX_VALUE);
|
||||
minDist[1] = 0;
|
||||
|
||||
// Declare a queue to store the updated nodes instead of traversing all nodes each loop for more efficiency
|
||||
Queue<Integer> queue = new LinkedList<>();
|
||||
queue.offer(1);
|
||||
|
||||
// Declare an array to record the times each node has been offered in the queue
|
||||
int[] count = new int[n + 1];
|
||||
count[1]++;
|
||||
|
||||
// Declare a boolean array to record if the current node is in the queue to optimise the processing
|
||||
boolean[] isInQueue = new boolean[n + 1];
|
||||
|
||||
// Declare a boolean value to check if there is a negative weight loop inside the graph
|
||||
boolean flag = false;
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
int curNode = queue.poll();
|
||||
isInQueue[curNode] = false; // Represents the current node is not in the queue after being polled
|
||||
for (Edge edge : graph.get(curNode)) {
|
||||
if (minDist[edge.to] > minDist[edge.from] + edge.val) { // Start relaxing the edge
|
||||
minDist[edge.to] = minDist[edge.from] + edge.val;
|
||||
if (!isInQueue[edge.to]) { // Don't add the node if it's already in the queue
|
||||
queue.offer(edge.to);
|
||||
count[edge.to]++;
|
||||
isInQueue[edge.to] = true;
|
||||
}
|
||||
|
||||
if (count[edge.to] == n) { // If some node has been offered in the queue more than n-1 times
|
||||
flag = true;
|
||||
while (!queue.isEmpty()) queue.poll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
System.out.println("circle");
|
||||
} else if (minDist[n] == Integer.MAX_VALUE) {
|
||||
System.out.println("unconnected");
|
||||
} else {
|
||||
System.out.println(minDist[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
|
@ -636,6 +636,71 @@ dijkstra 是贪心的思路 每一次搜索都只会找距离源点最近的非
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
```Java
|
||||
import java.util.*;
|
||||
|
||||
public class Main {
|
||||
// 基于Bellman_for一般解法解决单源最短路径问题
|
||||
// Define an inner class Edge
|
||||
static class Edge {
|
||||
int from;
|
||||
int to;
|
||||
int val;
|
||||
public Edge(int from, int to, int val) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Input processing
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int n = sc.nextInt();
|
||||
int m = sc.nextInt();
|
||||
|
||||
List<Edge> graph = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
int from = sc.nextInt();
|
||||
int to = sc.nextInt();
|
||||
int val = sc.nextInt();
|
||||
graph.add(new Edge(from, to, val));
|
||||
}
|
||||
|
||||
int src = sc.nextInt();
|
||||
int dst = sc.nextInt();
|
||||
int k = sc.nextInt();
|
||||
|
||||
int[] minDist = new int[n + 1];
|
||||
int[] minDistCopy;
|
||||
|
||||
Arrays.fill(minDist, Integer.MAX_VALUE);
|
||||
minDist[src] = 0;
|
||||
|
||||
for (int i = 0; i < k + 1; i++) { // Relax all edges k + 1 times
|
||||
minDistCopy = Arrays.copyOf(minDist, n + 1);
|
||||
for (Edge edge : graph) {
|
||||
int from = edge.from;
|
||||
int to = edge.to;
|
||||
int val = edge.val;
|
||||
// Use minDistCopy to calculate minDist
|
||||
if (minDistCopy[from] != Integer.MAX_VALUE && minDist[to] > minDistCopy[from] + val) {
|
||||
minDist[to] = minDistCopy[from] + val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output printing
|
||||
if (minDist[dst] == Integer.MAX_VALUE) {
|
||||
System.out.println("unreachable");
|
||||
} else {
|
||||
System.out.println(minDist[dst]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
|
@ -246,29 +246,36 @@ public class Main {
|
||||
|
||||
```python
|
||||
|
||||
def dfs(grid, visited, x, y):
|
||||
dir = [(0, 1), (1, 0), (-1, 0), (0, -1)] # 四个方向
|
||||
for d in dir:
|
||||
nextx, nexty = x + d[0], y + d[1]
|
||||
if 0 <= nextx < len(grid) and 0 <= nexty < len(grid[0]):
|
||||
if not visited[nextx][nexty] and grid[nextx][nexty] == 1: # 没有访问过的 同时 是陆地的
|
||||
visited[nextx][nexty] = True
|
||||
dfs(grid, visited, nextx, nexty)
|
||||
from collections import deque
|
||||
directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]
|
||||
def bfs(grid, visited, x, y):
|
||||
que = deque([])
|
||||
que.append([x,y])
|
||||
while que:
|
||||
cur_x, cur_y = que.popleft()
|
||||
for i, j in directions:
|
||||
next_x = cur_x + i
|
||||
next_y = cur_y + j
|
||||
if next_y < 0 or next_x < 0 or next_x >= len(grid) or next_y >= len(grid[0]):
|
||||
continue
|
||||
if not visited[next_x][next_y] and grid[next_x][next_y] == 1:
|
||||
visited[next_x][next_y] = True
|
||||
que.append([next_x, next_y])
|
||||
|
||||
|
||||
def main():
|
||||
n, m = map(int, input().split())
|
||||
grid = [list(map(int, input().split())) for _ in range(n)]
|
||||
grid = []
|
||||
for i in range(n):
|
||||
grid.append(list(map(int, input().split())))
|
||||
visited = [[False] * m for _ in range(n)]
|
||||
|
||||
result = 0
|
||||
res = 0
|
||||
for i in range(n):
|
||||
for j in range(m):
|
||||
if not visited[i][j] and grid[i][j] == 1:
|
||||
visited[i][j] = True
|
||||
result += 1 # 遇到没访问过的陆地,+1
|
||||
dfs(grid, visited, i, j) # 将与其链接的陆地都标记上 True
|
||||
|
||||
print(result)
|
||||
if grid[i][j] == 1 and not visited[i][j]:
|
||||
res += 1
|
||||
bfs(grid, visited, i, j)
|
||||
print(res)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -140,6 +140,63 @@ int main() {
|
||||
|
||||
### Python
|
||||
|
||||
#### 广搜版
|
||||
```Python
|
||||
from collections import deque
|
||||
|
||||
n, m = list(map(int, input().split()))
|
||||
g = []
|
||||
for _ in range(n):
|
||||
row = list(map(int,input().split()))
|
||||
g.append(row)
|
||||
|
||||
directions = [(1,0),(-1,0),(0,1),(0,-1)]
|
||||
count = 0
|
||||
|
||||
def bfs(r,c,mode):
|
||||
global count
|
||||
q = deque()
|
||||
q.append((r,c))
|
||||
count += 1
|
||||
|
||||
while q:
|
||||
r, c = q.popleft()
|
||||
if mode:
|
||||
g[r][c] = 2
|
||||
|
||||
for di in directions:
|
||||
next_r = r + di[0]
|
||||
next_c = c + di[1]
|
||||
if next_c < 0 or next_c >= m or next_r < 0 or next_r >= n:
|
||||
continue
|
||||
if g[next_r][next_c] == 1:
|
||||
q.append((next_r,next_c))
|
||||
if mode:
|
||||
g[r][c] = 2
|
||||
|
||||
count += 1
|
||||
|
||||
|
||||
for i in range(n):
|
||||
if g[i][0] == 1: bfs(i,0,True)
|
||||
if g[i][m-1] == 1: bfs(i, m-1,True)
|
||||
|
||||
for j in range(m):
|
||||
if g[0][j] == 1: bfs(0,j,1)
|
||||
if g[n-1][j] == 1: bfs(n-1,j,1)
|
||||
|
||||
for i in range(n):
|
||||
for j in range(m):
|
||||
if g[i][j] == 2:
|
||||
g[i][j] = 1
|
||||
else:
|
||||
g[i][j] = 0
|
||||
|
||||
for row in g:
|
||||
print(" ".join(map(str, row)))
|
||||
```
|
||||
|
||||
|
||||
### Go
|
||||
|
||||
### Rust
|
||||
|
@ -366,12 +366,289 @@ public class Main {
|
||||
|
||||
### Python
|
||||
|
||||
|
||||
#### BFS
|
||||
```Python
|
||||
from typing import List
|
||||
from collections import defaultdict
|
||||
|
||||
class Solution:
|
||||
def __init__(self):
|
||||
self.direction = [(1,0),(-1,0),(0,1),(0,-1)]
|
||||
self.res = 0
|
||||
self.count = 0
|
||||
self.idx = 1
|
||||
self.count_area = defaultdict(int)
|
||||
|
||||
def max_area_island(self, grid: List[List[int]]) -> int:
|
||||
if not grid or len(grid) == 0 or len(grid[0]) == 0:
|
||||
return 0
|
||||
|
||||
for i in range(len(grid)):
|
||||
for j in range(len(grid[0])):
|
||||
if grid[i][j] == 1:
|
||||
self.count = 0
|
||||
self.idx += 1
|
||||
self.dfs(grid,i,j)
|
||||
# print(grid)
|
||||
self.check_area(grid)
|
||||
# print(self.count_area)
|
||||
|
||||
if self.check_largest_connect_island(grid=grid):
|
||||
return self.res + 1
|
||||
return max(self.count_area.values())
|
||||
|
||||
def dfs(self,grid,row,col):
|
||||
grid[row][col] = self.idx
|
||||
self.count += 1
|
||||
for dr,dc in self.direction:
|
||||
_row = dr + row
|
||||
_col = dc + col
|
||||
if 0<=_row<len(grid) and 0<=_col<len(grid[0]) and grid[_row][_col] == 1:
|
||||
self.dfs(grid,_row,_col)
|
||||
return
|
||||
|
||||
def check_area(self,grid):
|
||||
m, n = len(grid), len(grid[0])
|
||||
for row in range(m):
|
||||
for col in range(n):
|
||||
self.count_area[grid[row][col]] = self.count_area.get(grid[row][col],0) + 1
|
||||
return
|
||||
|
||||
def check_largest_connect_island(self,grid):
|
||||
m, n = len(grid), len(grid[0])
|
||||
has_connect = False
|
||||
for row in range(m):
|
||||
for col in range(n):
|
||||
if grid[row][col] == 0:
|
||||
has_connect = True
|
||||
area = 0
|
||||
visited = set()
|
||||
for dr, dc in self.direction:
|
||||
_row = row + dr
|
||||
_col = col + dc
|
||||
if 0<=_row<len(grid) and 0<=_col<len(grid[0]) and grid[_row][_col] != 0 and grid[_row][_col] not in visited:
|
||||
visited.add(grid[_row][_col])
|
||||
area += self.count_area[grid[_row][_col]]
|
||||
self.res = max(self.res, area)
|
||||
|
||||
return has_connect
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
m, n = map(int, input().split())
|
||||
grid = []
|
||||
|
||||
for i in range(m):
|
||||
grid.append(list(map(int,input().split())))
|
||||
|
||||
|
||||
sol = Solution()
|
||||
print(sol.max_area_island(grid))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
```
|
||||
|
||||
|
||||
```Python
|
||||
import collections
|
||||
|
||||
directions = [[-1, 0], [0, 1], [0, -1], [1, 0]]
|
||||
area = 0
|
||||
|
||||
def dfs(i, j, grid, visited, num):
|
||||
global area
|
||||
|
||||
if visited[i][j]:
|
||||
return
|
||||
|
||||
visited[i][j] = True
|
||||
grid[i][j] = num # 标记岛屿号码
|
||||
area += 1
|
||||
|
||||
for x, y in directions:
|
||||
new_x = i + x
|
||||
new_y = j + y
|
||||
if (
|
||||
0 <= new_x < len(grid)
|
||||
and 0 <= new_y < len(grid[0])
|
||||
and grid[new_x][new_y] == "1"
|
||||
):
|
||||
dfs(new_x, new_y, grid, visited, num)
|
||||
|
||||
|
||||
def main():
|
||||
global area
|
||||
|
||||
N, M = map(int, input().strip().split())
|
||||
grid = []
|
||||
for i in range(N):
|
||||
grid.append(input().strip().split())
|
||||
visited = [[False] * M for _ in range(N)]
|
||||
rec = collections.defaultdict(int)
|
||||
|
||||
cnt = 2
|
||||
for i in range(N):
|
||||
for j in range(M):
|
||||
if grid[i][j] == "1":
|
||||
area = 0
|
||||
dfs(i, j, grid, visited, cnt)
|
||||
rec[cnt] = area # 纪录岛屿面积
|
||||
cnt += 1
|
||||
|
||||
res = 0
|
||||
for i in range(N):
|
||||
for j in range(M):
|
||||
if grid[i][j] == "0":
|
||||
max_island = 1 # 将水变为陆地,故从1开始计数
|
||||
v = set()
|
||||
for x, y in directions:
|
||||
new_x = i + x
|
||||
new_y = j + y
|
||||
if (
|
||||
0 <= new_x < len(grid)
|
||||
and 0 <= new_y < len(grid[0])
|
||||
and grid[new_x][new_y] != "0"
|
||||
and grid[new_x][new_y] not in v # 岛屿不可重复
|
||||
):
|
||||
max_island += rec[grid[new_x][new_y]]
|
||||
v.add(grid[new_x][new_y])
|
||||
res = max(res, max_island)
|
||||
|
||||
if res == 0:
|
||||
return max(rec.values()) # 无水的情况
|
||||
return res
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(main())
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
### Rust
|
||||
|
||||
### Javascript
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
let graph // 地图
|
||||
let N, M // 地图大小
|
||||
let visited // 访问过的节点, 标记岛屿
|
||||
const dir = [[0, 1], [1, 0], [0, -1], [-1, 0]] //方向
|
||||
|
||||
let count = 0 // 统计岛屿面积
|
||||
let areaMap = new Map() // 存储岛屿面积
|
||||
|
||||
|
||||
// 读取输入,初始化地图
|
||||
const initGraph = async () => {
|
||||
let line = await readline();
|
||||
[N, M] = line.split(' ').map(Number);
|
||||
graph = new Array(N).fill(0).map(() => new Array(M).fill(0))
|
||||
visited = new Array(N).fill(0).map(() => new Array(M).fill(0))
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
for (let j = 0; j < M; j++) {
|
||||
graph[i][j] = line[j]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 从(x,y)开始深度优先遍历地图
|
||||
* @param {*} graph 地图
|
||||
* @param {*} visited 可访问节点
|
||||
* @param {*} x 开始搜索节点的下标
|
||||
* @param {*} y 开始搜索节点的下标
|
||||
* @param {*} mark 当前岛屿的标记
|
||||
* @return {*}
|
||||
*/
|
||||
const dfs = (graph, visited, x, y, mark) => {
|
||||
if (visited[x][y] != 0) return
|
||||
visited[x][y] = mark
|
||||
count++
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
let nextx = x + dir[i][0]
|
||||
let nexty = y + dir[i][1]
|
||||
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue //越界, 跳过
|
||||
|
||||
// 已访问过, 或者是海洋, 跳过
|
||||
if (visited[nextx][nexty] != 0 || graph[nextx][nexty] == 0) continue
|
||||
|
||||
dfs(graph, visited, nextx, nexty, mark)
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
|
||||
// 读取输入,初始化地图
|
||||
await initGraph()
|
||||
|
||||
let isAllLand = true //标记整个地图都是陆地
|
||||
|
||||
let mark = 2 // 标记岛屿
|
||||
for (let i = 0; i < N; i++) {
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (graph[i][j] == 0 && isAllLand) isAllLand = false
|
||||
if (graph[i][j] === 1 && visited[i][j] === 0) {
|
||||
count = 0
|
||||
dfs(graph, visited, i, j, mark)
|
||||
areaMap.set(mark, count)
|
||||
mark++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 如果全是陆地, 直接返回面积
|
||||
if (isAllLand) {
|
||||
console.log(N * M);
|
||||
return
|
||||
}
|
||||
|
||||
let result = 0 // 记录最后结果
|
||||
let visitedIsland = new Map() //标记访问过的岛屿, 因为海洋四周可能是同一个岛屿, 需要标记避免重复统计面积
|
||||
for (let i = 0; i < N; i++) {
|
||||
for (let j = 0; j < M; j++) {
|
||||
if (visited[i][j] === 0) {
|
||||
count = 1 // 记录连接之后的岛屿数量
|
||||
visitedIsland.clear() // 每次使用时,清空
|
||||
|
||||
// 计算海洋周围岛屿面积
|
||||
for (let m = 0; m < 4; m++) {
|
||||
const nextx = i + dir[m][0]
|
||||
const nexty = j + dir[m][1]
|
||||
if (nextx < 0 || nextx >= N || nexty < 0 || nexty >= M) continue //越界, 跳过
|
||||
|
||||
const island = visited[nextx][nexty]
|
||||
if (island == 0 || visitedIsland.get(island)) continue// 四周是海洋或者访问过的陆地 跳过
|
||||
|
||||
// 标记为访问, 计算面积
|
||||
visitedIsland.set(island, true)
|
||||
count += areaMap.get(visited[nextx][nexty])
|
||||
}
|
||||
|
||||
result = Math.max(result, count)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -290,6 +290,42 @@ int main() {
|
||||
### Java
|
||||
|
||||
### Python
|
||||
BFS算法
|
||||
```Python
|
||||
import collections
|
||||
|
||||
path = set() # 纪录 BFS 所经过之节点
|
||||
|
||||
def bfs(root, graph):
|
||||
global path
|
||||
|
||||
que = collections.deque([root])
|
||||
while que:
|
||||
cur = que.popleft()
|
||||
path.add(cur)
|
||||
|
||||
for nei in graph[cur]:
|
||||
que.append(nei)
|
||||
graph[cur] = []
|
||||
return
|
||||
|
||||
def main():
|
||||
N, K = map(int, input().strip().split())
|
||||
graph = collections.defaultdict(list)
|
||||
for _ in range(K):
|
||||
src, dest = map(int, input().strip().split())
|
||||
graph[src].append(dest)
|
||||
|
||||
bfs(1, graph)
|
||||
if path == {i for i in range(1, N + 1)}:
|
||||
return 1
|
||||
return -1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(main())
|
||||
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
|
@ -223,6 +223,72 @@ class DisJoint{
|
||||
|
||||
### Javascript
|
||||
|
||||
```java
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
|
||||
let N, M // 节点数和边数
|
||||
let source, destination // 起点 终点
|
||||
let father = [] // 并查集
|
||||
|
||||
|
||||
// 并查集初始化
|
||||
const init = () => {
|
||||
for (let i = 1; i <= N; i++) father[i] = i;
|
||||
}
|
||||
|
||||
// 并查集里寻根的过程
|
||||
const find = (u) => {
|
||||
return u == father[u] ? u : father[u] = find(father[u])
|
||||
}
|
||||
|
||||
// 将v->u 这条边加入并查集
|
||||
const join = (u, v) => {
|
||||
u = find(u)
|
||||
v = find(v)
|
||||
if (u == v) return // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
|
||||
father[v] = u
|
||||
}
|
||||
|
||||
// 判断 u 和 v是否找到同一个根
|
||||
const isSame = (u, v) => {
|
||||
u = find(u)
|
||||
v = find(v)
|
||||
return u == v
|
||||
}
|
||||
|
||||
|
||||
(async function () {
|
||||
// 读取第一行输入
|
||||
let line = await readline();
|
||||
[N, M] = line.split(' ').map(Number);
|
||||
|
||||
// 初始化并查集
|
||||
father = new Array(N)
|
||||
init()
|
||||
|
||||
// 读取边信息, 加入并查集
|
||||
for (let i = 0; i < M; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
join(line[0], line[1])
|
||||
}
|
||||
|
||||
// 读取起点和终点
|
||||
line = await readline(); //JS注意这里的冒号
|
||||
[source, destination] = line.split(' ').map(Number)
|
||||
|
||||
if (isSame(source, destination)) return console.log(1);
|
||||
console.log(0);
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -141,6 +141,70 @@ int main() {
|
||||
|
||||
### Javascript
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
|
||||
let N // 节点数和边数
|
||||
let father = [] // 并查集
|
||||
|
||||
|
||||
// 并查集初始化
|
||||
const init = () => {
|
||||
for (let i = 1; i <= N; i++) father[i] = i;
|
||||
}
|
||||
|
||||
// 并查集里寻根的过程
|
||||
const find = (u) => {
|
||||
return u == father[u] ? u : father[u] = find(father[u])
|
||||
}
|
||||
|
||||
// 将v->u 这条边加入并查集
|
||||
const join = (u, v) => {
|
||||
u = find(u)
|
||||
v = find(v)
|
||||
if (u == v) return // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
|
||||
father[v] = u
|
||||
}
|
||||
|
||||
// 判断 u 和 v是否找到同一个根
|
||||
const isSame = (u, v) => {
|
||||
u = find(u)
|
||||
v = find(v)
|
||||
return u == v
|
||||
}
|
||||
|
||||
|
||||
(async function () {
|
||||
// 读取第一行输入
|
||||
let line = await readline();
|
||||
N = Number(line);
|
||||
|
||||
// 初始化并查集
|
||||
father = new Array(N)
|
||||
init()
|
||||
|
||||
// 读取边信息, 加入并查集
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
|
||||
if (!isSame(line[0], line[1])) {
|
||||
join(line[0], line[1])
|
||||
}else{
|
||||
console.log(line[0], line[1]);
|
||||
break
|
||||
}
|
||||
}
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -254,6 +254,119 @@ int main() {
|
||||
|
||||
### Javascript
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
|
||||
let N // 节点数和边数
|
||||
let father = [] // 并查集
|
||||
let edges = [] // 边集
|
||||
let inDegree = [] // 入度
|
||||
|
||||
|
||||
// 并查集初始化
|
||||
const init = () => {
|
||||
for (let i = 1; i <= N; i++) father[i] = i;
|
||||
}
|
||||
|
||||
// 并查集里寻根的过程
|
||||
const find = (u) => {
|
||||
return u == father[u] ? u : father[u] = find(father[u])
|
||||
}
|
||||
|
||||
// 将v->u 这条边加入并查集
|
||||
const join = (u, v) => {
|
||||
u = find(u)
|
||||
v = find(v)
|
||||
if (u == v) return // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
|
||||
father[v] = u
|
||||
}
|
||||
|
||||
// 判断 u 和 v是否找到同一个根
|
||||
const isSame = (u, v) => {
|
||||
u = find(u)
|
||||
v = find(v)
|
||||
return u == v
|
||||
}
|
||||
|
||||
// 判断删除一条边后是不是树
|
||||
const isTreeAfterRemoveEdge = (edges, edge) => {
|
||||
// 初始化并查集
|
||||
init()
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (i == edge) continue
|
||||
if (isSame(edges[i][0], edges[i][1])) { // 构成有向环了,一定不是树
|
||||
return false
|
||||
}
|
||||
join(edges[i][0], edges[i][1])
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 在有向图里找到删除的那条边, 使其成为树
|
||||
const getRemoveEdge = (edges) => {
|
||||
// 初始化并查集
|
||||
init()
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (isSame(edges[i][0], edges[i][1])) { // 构成有向环了,就是要删除的边
|
||||
console.log(edges[i][0], edges[i][1]);
|
||||
return
|
||||
} else {
|
||||
join(edges[i][0], edges[i][1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
(async function () {
|
||||
// 读取第一行输入
|
||||
let line = await readline();
|
||||
N = Number(line);
|
||||
|
||||
// 读取边信息, 统计入度
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.split(' ').map(Number)
|
||||
|
||||
edges.push(line)
|
||||
|
||||
inDegree[line[1]] = (inDegree[line[1]] || 0) + 1
|
||||
}
|
||||
|
||||
// 找到入度为2的节点
|
||||
let vec = [] // 记录入度为2的边(如果有的话就两条边)
|
||||
// 找入度为2的节点所对应的边,注意要倒序,因为优先删除最后出现的一条边
|
||||
for (let i = N - 1; i >= 0; i--) {
|
||||
if (inDegree[edges[i][1]] == 2) {
|
||||
vec.push(i)
|
||||
}
|
||||
}
|
||||
|
||||
// 情况一、情况二
|
||||
if (vec.length > 0) {
|
||||
// 放在vec里的边已经按照倒叙放的,所以这里就优先删vec[0]这条边
|
||||
if (isTreeAfterRemoveEdge(edges, vec[0])) {
|
||||
console.log(edges[vec[0]][0], edges[vec[0]][1]);
|
||||
} else {
|
||||
console.log(edges[vec[1]][0], edges[vec[1]][1]);
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// 情况三
|
||||
// 明确没有入度为2的情况,那么一定有有向环,找到构成环的边返回就可以了
|
||||
getRemoveEdge(edges)
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -38,7 +38,7 @@ ebc
|
||||
dec
|
||||
dfc
|
||||
yhn
|
||||
```
|
||||
```
|
||||
|
||||
输出示例
|
||||
|
||||
@ -217,6 +217,38 @@ public class Main {
|
||||
```
|
||||
|
||||
### Python
|
||||
```Python
|
||||
def judge(s1,s2):
|
||||
count=0
|
||||
for i in range(len(s1)):
|
||||
if s1[i]!=s2[i]:
|
||||
count+=1
|
||||
return count==1
|
||||
|
||||
if __name__=='__main__':
|
||||
n=int(input())
|
||||
beginstr,endstr=map(str,input().split())
|
||||
if beginstr==endstr:
|
||||
print(0)
|
||||
exit()
|
||||
strlist=[]
|
||||
for i in range(n):
|
||||
strlist.append(input())
|
||||
|
||||
# use bfs
|
||||
visit=[False for i in range(n)]
|
||||
queue=[[beginstr,1]]
|
||||
while queue:
|
||||
str,step=queue.pop(0)
|
||||
if judge(str,endstr):
|
||||
print(step+1)
|
||||
exit()
|
||||
for i in range(n):
|
||||
if visit[i]==False and judge(strlist[i],str):
|
||||
visit[i]=True
|
||||
queue.append([strlist[i],step+1])
|
||||
print(0)
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
@ -224,6 +256,80 @@ public class Main {
|
||||
|
||||
### Javascript
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
let N //输入字符串个数
|
||||
let beginStr //开始字符串
|
||||
let endStr //结束字符串
|
||||
let strSet = new Set() //字符串集合
|
||||
let visitedMap = new Map() //访问过的字符串
|
||||
|
||||
// 读取输入,初始化地图
|
||||
const init = async () => {
|
||||
let line = await readline();
|
||||
line = line.trim()
|
||||
N = Number(line);
|
||||
|
||||
line = await readline();
|
||||
line = line.trim().split(' ')
|
||||
beginStr = line[0]
|
||||
endStr = line[1]
|
||||
|
||||
for (let i = 0; i < N; i++) {
|
||||
line = await readline()
|
||||
line = line.trim()
|
||||
strSet.add(line.trim())
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
|
||||
// 读取输入,初始化数据
|
||||
await init()
|
||||
|
||||
// 初始化队列
|
||||
let queue = []
|
||||
queue.push(beginStr)
|
||||
|
||||
// 初始化visitMap
|
||||
visitedMap.set(beginStr, 1)
|
||||
|
||||
while (queue.length) {
|
||||
let word = queue.shift()
|
||||
let path = visitedMap.get(word)
|
||||
|
||||
// 遍历26个字母
|
||||
for (let i = 0; i < word.length; i++) {
|
||||
let newWord = word.split('') // 用一个新字符串替换str,因为每次要置换一个字符
|
||||
for (let j = 0; j < 26; j++) {
|
||||
newWord[i] = String.fromCharCode('a'.charCodeAt() + j)
|
||||
// 发现替换字母后,字符串与终点字符串相同
|
||||
if (newWord.join('') === endStr) {
|
||||
console.log(path + 1);
|
||||
return 0; // 找到了路径
|
||||
}
|
||||
|
||||
// 字符串集合里出现了newWord,并且newWord没有被访问过
|
||||
if (strSet.has(newWord.join('')) && !visitedMap.has(newWord.join(''))) {
|
||||
// 添加访问信息,并将新字符串放到队列中
|
||||
queue.push(newWord.join(''))
|
||||
visitedMap.set(newWord.join(''), path + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(0);
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -193,7 +193,7 @@
|
||||
|
||||
理解思想后,确实不难,但代码写起来也不容易。
|
||||
|
||||
为了每次可以找到所有节点的入度信息,我们要在初始话的时候,就把每个节点的入度 和 每个节点的依赖关系做统计。
|
||||
为了每次可以找到所有节点的入度信息,我们要在初始化的时候,就把每个节点的入度 和 每个节点的依赖关系做统计。
|
||||
|
||||
代码如下:
|
||||
|
||||
@ -451,6 +451,80 @@ if __name__ == "__main__":
|
||||
|
||||
### Javascript
|
||||
|
||||
```javascript
|
||||
const r1 = require('readline').createInterface({ input: process.stdin });
|
||||
// 创建readline接口
|
||||
let iter = r1[Symbol.asyncIterator]();
|
||||
// 创建异步迭代器
|
||||
const readline = async () => (await iter.next()).value;
|
||||
|
||||
|
||||
let N, M // 节点数和边数
|
||||
let inDegrees = [] // 入度
|
||||
let umap = new Map() // 记录文件依赖关系
|
||||
let result = [] // 结果
|
||||
|
||||
|
||||
// 根据输入, 初始化数据
|
||||
const init = async () => {
|
||||
// 读取第一行输入
|
||||
let line = await readline();
|
||||
[N, M] = line.split(' ').map(Number)
|
||||
|
||||
inDegrees = new Array(N).fill(0)
|
||||
|
||||
// 读取边集
|
||||
while (M--) {
|
||||
line = await readline();
|
||||
let [x, y] = line.split(' ').map(Number)
|
||||
|
||||
// 记录入度
|
||||
inDegrees[y]++
|
||||
|
||||
// 记录x指向哪些文件
|
||||
if (!umap.has(x)) {
|
||||
umap.set(x, [y])
|
||||
} else {
|
||||
umap.get(x).push(y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(async function () {
|
||||
// 根据输入, 初始化数据
|
||||
await init()
|
||||
|
||||
let queue = [] // 入度为0的节点
|
||||
for (let i = 0; i < N; i++) {
|
||||
if (inDegrees[i] == 0) {
|
||||
queue.push(i)
|
||||
}
|
||||
}
|
||||
|
||||
while (queue.length) {
|
||||
let cur = queue.shift() //当前文件
|
||||
|
||||
result.push(cur)
|
||||
|
||||
let files = umap.get(cur) // 当前文件指向的文件
|
||||
|
||||
// 当前文件指向的文件入度减1
|
||||
if (files && files.length) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
inDegrees[files[i]]--
|
||||
if (inDegrees[files[i]] == 0) queue.push(files[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 这里result.length == N 一定要判断, 因为可能存在环
|
||||
if (result.length == N) return console.log(result.join(' '))
|
||||
console.log(-1)
|
||||
})()
|
||||
```
|
||||
|
||||
|
||||
|
||||
### TypeScript
|
||||
|
||||
### PhP
|
||||
|
@ -437,6 +437,58 @@ print(dp[n - 1][bagweight])
|
||||
### Go
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var n, bagweight int // bagweight代表行李箱空间
|
||||
fmt.Scan(&n, &bagweight)
|
||||
|
||||
weight := make([]int, n) // 存储每件物品所占空间
|
||||
value := make([]int, n) // 存储每件物品价值
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
fmt.Scan(&weight[i])
|
||||
}
|
||||
for j := 0; j < n; j++ {
|
||||
fmt.Scan(&value[j])
|
||||
}
|
||||
// dp数组, dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值
|
||||
dp := make([][]int, n)
|
||||
for i := range dp {
|
||||
dp[i] = make([]int, bagweight + 1)
|
||||
}
|
||||
|
||||
// 初始化, 因为需要用到dp[i - 1]的值
|
||||
// j < weight[0]已在上方被初始化为0
|
||||
// j >= weight[0]的值就初始化为value[0]
|
||||
for j := weight[0]; j <= bagweight; j++ {
|
||||
dp[0][j] = value[0]
|
||||
}
|
||||
|
||||
for i := 1; i < n; i++ { // 遍历科研物品
|
||||
for j := 0; j <= bagweight; j++ { // 遍历行李箱容量
|
||||
if j < weight[i] {
|
||||
dp[i][j] = dp[i-1][j] // 如果装不下这个物品,那么就继承dp[i - 1][j]的值
|
||||
} else {
|
||||
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(dp[n-1][bagweight])
|
||||
}
|
||||
|
||||
func max(x, y int) int {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Javascript
|
||||
|
@ -313,7 +313,7 @@ for i in range(1, n):
|
||||
print(dp[n - 1][bagweight])
|
||||
|
||||
```
|
||||
### Go
|
||||
### Go
|
||||
```go
|
||||
package main
|
||||
|
||||
@ -322,46 +322,41 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
var n, bagweight int
|
||||
fmt.Scan(&n, &bagweight)
|
||||
// 读取 M 和 N
|
||||
var M, N int
|
||||
fmt.Scan(&M, &N)
|
||||
|
||||
weight := make([]int, n)
|
||||
value := make([]int, n)
|
||||
costs := make([]int, M)
|
||||
values := make([]int, M)
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
fmt.Scan(&weight[i])
|
||||
for i := 0; i < M; i++ {
|
||||
fmt.Scan(&costs[i])
|
||||
}
|
||||
for j := 0; j < n; j++ {
|
||||
fmt.Scan(&value[j])
|
||||
for j := 0; j < M; j++ {
|
||||
fmt.Scan(&values[j])
|
||||
}
|
||||
|
||||
dp := make([][]int, n)
|
||||
for i := range dp {
|
||||
dp[i] = make([]int, bagweight+1)
|
||||
}
|
||||
// 创建一个动态规划数组dp,初始值为0
|
||||
dp := make([]int, N + 1)
|
||||
|
||||
for j := weight[0]; j <= bagweight; j++ {
|
||||
dp[0][j] = value[0]
|
||||
}
|
||||
|
||||
for i := 1; i < n; i++ {
|
||||
for j := 0; j <= bagweight; j++ {
|
||||
if j < weight[i] {
|
||||
dp[i][j] = dp[i-1][j]
|
||||
} else {
|
||||
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
|
||||
}
|
||||
// 外层循环遍历每个类型的研究材料
|
||||
for i := 0; i < M; i++ {
|
||||
// 内层循环从 N 空间逐渐减少到当前研究材料所占空间
|
||||
for j := N; j >= costs[i]; j-- {
|
||||
// 考虑当前研究材料选择和不选择的情况,选择最大值
|
||||
dp[j] = max(dp[j], dp[j-costs[i]] + values[i])
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(dp[n-1][bagweight])
|
||||
// 输出dp[N],即在给定 N 行李空间可以携带的研究材料最大价值
|
||||
fmt.Println(dp[N])
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
func max(x, y int) int {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return b
|
||||
return y
|
||||
}
|
||||
|
||||
```
|
||||
|
Reference in New Issue
Block a user