Merge branch 'master' into fix-bug-description

This commit is contained in:
程序员Carl
2024-08-26 10:18:44 +08:00
committed by GitHub
23 changed files with 1325 additions and 54 deletions

View File

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

View File

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

View File

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

View File

@ -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)
## 其他语言版本

View File

@ -14,7 +14,7 @@
![226.翻转二叉树](https://code-thinking-1253855093.file.myqcloud.com/pics/20210203192644329.png)
这道题目背后有一个让程序员心酸的故事,听说 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>

View File

@ -44,7 +44,7 @@ queue.empty(); // 返回 false
这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。
使用栈来模队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。
使用栈来模队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。
下面动画模拟以下队列的执行过程:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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: 从xy开始深度优先遍历地图
* @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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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