mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-05 22:59:31 +08:00
Update
This commit is contained in:
@ -214,6 +214,7 @@ class Solution:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
```
|
```
|
||||||
|
贪心法
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def maxSubArray(self, nums):
|
def maxSubArray(self, nums):
|
||||||
@ -226,8 +227,18 @@ class Solution:
|
|||||||
if count <= 0: # 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
|
if count <= 0: # 相当于重置最大子序起始位置,因为遇到负数一定是拉低总和
|
||||||
count = 0
|
count = 0
|
||||||
return result
|
return result
|
||||||
|
```
|
||||||
|
动态规划
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def maxSubArray(self, nums: List[int]) -> int:
|
||||||
|
dp = [0] * len(nums)
|
||||||
|
dp[0] = nums[0]
|
||||||
|
res = nums[0]
|
||||||
|
for i in range(1, len(nums)):
|
||||||
|
dp[i] = max(dp[i-1] + nums[i], nums[i])
|
||||||
|
res = max(res, dp[i])
|
||||||
|
return res
|
||||||
```
|
```
|
||||||
### Go
|
### Go
|
||||||
贪心法
|
贪心法
|
||||||
|
@ -184,6 +184,16 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
### Go:
|
### Go:
|
||||||
```go
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
func climbStairs(n int, m int) int {
|
func climbStairs(n int, m int) int {
|
||||||
dp := make([]int, n+1)
|
dp := make([]int, n+1)
|
||||||
dp[0] = 1
|
dp[0] = 1
|
||||||
|
@ -467,9 +467,37 @@ class Solution:
|
|||||||
num = int(s[start:end+1])
|
num = int(s[start:end+1])
|
||||||
return 0 <= num <= 255
|
return 0 <= num <= 255
|
||||||
|
|
||||||
|
回溯(版本三)
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def restoreIpAddresses(self, s: str) -> List[str]:
|
||||||
|
result = []
|
||||||
|
self.backtracking(s, 0, [], result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def backtracking(self, s, startIndex, path, result):
|
||||||
|
if startIndex == len(s):
|
||||||
|
result.append('.'.join(path[:]))
|
||||||
|
return
|
||||||
|
|
||||||
|
for i in range(startIndex, min(startIndex+3, len(s))):
|
||||||
|
# 如果 i 往后遍历了,并且当前地址的第一个元素是 0 ,就直接退出
|
||||||
|
if i > startIndex and s[startIndex] == '0':
|
||||||
|
break
|
||||||
|
# 比如 s 长度为 5,当前遍历到 i = 3 这个元素
|
||||||
|
# 因为还没有执行任何操作,所以此时剩下的元素数量就是 5 - 3 = 2 ,即包括当前的 i 本身
|
||||||
|
# path 里面是当前包含的子串,所以有几个元素就表示储存了几个地址
|
||||||
|
# 所以 (4 - len(path)) * 3 表示当前路径至多能存放的元素个数
|
||||||
|
# 4 - len(path) 表示至少要存放的元素个数
|
||||||
|
if (4 - len(path)) * 3 < len(s) - i or 4 - len(path) > len(s) - i:
|
||||||
|
break
|
||||||
|
if i - startIndex == 2:
|
||||||
|
if not int(s[startIndex:i+1]) <= 255:
|
||||||
|
break
|
||||||
|
path.append(s[startIndex:i+1])
|
||||||
|
self.backtracking(s, i+1, path, result)
|
||||||
|
path.pop()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
|
@ -609,10 +609,13 @@ class Solution:
|
|||||||
while stack:
|
while stack:
|
||||||
node = stack.pop()
|
node = stack.pop()
|
||||||
if node:
|
if node:
|
||||||
stack.append(node)
|
stack.append(node) # 中
|
||||||
stack.append(None)
|
stack.append(None)
|
||||||
if node.left: stack.append(node.left)
|
# 采用数组进行迭代,先将右节点加入,保证左节点能够先出栈
|
||||||
if node.right: stack.append(node.right)
|
if node.right: # 右
|
||||||
|
stack.append(node.right)
|
||||||
|
if node.left: # 左
|
||||||
|
stack.append(node.left)
|
||||||
else:
|
else:
|
||||||
real_node = stack.pop()
|
real_node = stack.pop()
|
||||||
left, right = height_map.get(real_node.left, 0), height_map.get(real_node.right, 0)
|
left, right = height_map.get(real_node.left, 0), height_map.get(real_node.right, 0)
|
||||||
|
@ -158,7 +158,7 @@ i从0开始累加rest[i],和记为curSum,一旦curSum小于零,说明[0, i
|
|||||||
|
|
||||||
如果 curSum<0 说明 区间和1 + 区间和2 < 0, 那么 假设从上图中的位置开始计数curSum不会小于0的话,就是 区间和2>0。
|
如果 curSum<0 说明 区间和1 + 区间和2 < 0, 那么 假设从上图中的位置开始计数curSum不会小于0的话,就是 区间和2>0。
|
||||||
|
|
||||||
区间和1 + 区间和2 < 0 同时 区间和2>0,只能说明区间和1 < 0, 那么就会从假设的箭头初就开始从新选择其实位置了。
|
区间和1 + 区间和2 < 0 同时 区间和2>0,只能说明区间和1 < 0, 那么就会从假设的箭头初就开始从新选择起始位置了。
|
||||||
|
|
||||||
|
|
||||||
**那么局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。全局最优:找到可以跑一圈的起始位置**。
|
**那么局部最优:当前累加rest[i]的和curSum一旦小于0,起始位置至少要是i+1,因为从i之前开始一定不行。全局最优:找到可以跑一圈的起始位置**。
|
||||||
|
@ -475,7 +475,45 @@ class Solution:
|
|||||||
words = words[::-1] # 反转单词
|
words = words[::-1] # 反转单词
|
||||||
return ' '.join(words) #列表转换成字符串
|
return ' '.join(words) #列表转换成字符串
|
||||||
```
|
```
|
||||||
|
(版本四) 将字符串转换为列表后,使用双指针去除空格
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def single_reverse(self, s, start: int, end: int):
|
||||||
|
while start < end:
|
||||||
|
s[start], s[end] = s[end], s[start]
|
||||||
|
start += 1
|
||||||
|
end -= 1
|
||||||
|
|
||||||
|
def reverseWords(self, s: str) -> str:
|
||||||
|
result = ""
|
||||||
|
fast = 0
|
||||||
|
# 1. 首先将原字符串反转并且除掉空格, 并且加入到新的字符串当中
|
||||||
|
# 由于Python字符串的不可变性,因此只能转换为列表进行处理
|
||||||
|
s = list(s)
|
||||||
|
s.reverse()
|
||||||
|
while fast < len(s):
|
||||||
|
if s[fast] != " ":
|
||||||
|
if len(result) != 0:
|
||||||
|
result += " "
|
||||||
|
while s[fast] != " " and fast < len(s):
|
||||||
|
result += s[fast]
|
||||||
|
fast += 1
|
||||||
|
else:
|
||||||
|
fast += 1
|
||||||
|
# 2.其次将每个单词进行翻转操作
|
||||||
|
slow = 0
|
||||||
|
fast = 0
|
||||||
|
result = list(result)
|
||||||
|
while fast <= len(result):
|
||||||
|
if fast == len(result) or result[fast] == " ":
|
||||||
|
self.single_reverse(result, slow, fast - 1)
|
||||||
|
slow = fast + 1
|
||||||
|
fast += 1
|
||||||
|
else:
|
||||||
|
fast += 1
|
||||||
|
|
||||||
|
return "".join(result)
|
||||||
|
```
|
||||||
### Go:
|
### Go:
|
||||||
|
|
||||||
版本一:
|
版本一:
|
||||||
|
@ -454,7 +454,11 @@ impl Solution {
|
|||||||
p: Option<Rc<RefCell<TreeNode>>>,
|
p: Option<Rc<RefCell<TreeNode>>>,
|
||||||
q: Option<Rc<RefCell<TreeNode>>>,
|
q: Option<Rc<RefCell<TreeNode>>>,
|
||||||
) -> Option<Rc<RefCell<TreeNode>>> {
|
) -> Option<Rc<RefCell<TreeNode>>> {
|
||||||
if root == p || root == q || root.is_none() {
|
if root.is_none() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
if Rc::ptr_eq(root.as_ref().unwrap(), p.as_ref().unwrap())
|
||||||
|
|| Rc::ptr_eq(root.as_ref().unwrap(), q.as_ref().unwrap()) {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
let left = Self::lowest_common_ancestor(
|
let left = Self::lowest_common_ancestor(
|
||||||
|
@ -337,6 +337,29 @@ pub fn length_of_lis(nums: Vec<i32>) -> i32 {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Cangjie:
|
||||||
|
|
||||||
|
```cangjie
|
||||||
|
func lengthOfLIS(nums: Array<Int64>): Int64 {
|
||||||
|
let n = nums.size
|
||||||
|
if (n <= 1) {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
let dp = Array(n, item: 1)
|
||||||
|
var res = 0
|
||||||
|
for (i in 1..n) {
|
||||||
|
for (j in 0..i) {
|
||||||
|
if (nums[i] > nums[j]) {
|
||||||
|
dp[i] = max(dp[i], dp[j] + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = max(dp[i], res)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
|
@ -243,6 +243,29 @@ class Solution {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
贪心
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int integerBreak(int n) {
|
||||||
|
// with 贪心
|
||||||
|
// 通过数学原理拆出更多的3乘积越大,则
|
||||||
|
/**
|
||||||
|
@Param: an int, the integer we need to break.
|
||||||
|
@Return: an int, the maximum integer after breaking
|
||||||
|
@Method: Using math principle to solve this problem
|
||||||
|
@Time complexity: O(1)
|
||||||
|
**/
|
||||||
|
if(n == 2) return 1;
|
||||||
|
if(n == 3) return 2;
|
||||||
|
int result = 1;
|
||||||
|
while(n > 4) {
|
||||||
|
n-=3;
|
||||||
|
result *=3;
|
||||||
|
}
|
||||||
|
return result*n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Python
|
### Python
|
||||||
动态规划(版本一)
|
动态规划(版本一)
|
||||||
|
@ -177,7 +177,7 @@ KMP算法中next数组为什么遇到字符不匹配的时候可以找到上一
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
这里有录友就想:如果字符串s 是有是有最小重复子串p组成,最长相等前后缀就不能更长一些? 例如这样:
|
这里有录友就想:如果字符串s 是由最小重复子串p组成,最长相等前后缀就不能更长一些? 例如这样:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -884,3 +884,4 @@ public int[] GetNext(string s)
|
|||||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -706,6 +706,57 @@ class Solution:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
|
二维dp
|
||||||
|
```go
|
||||||
|
func findTargetSumWays(nums []int, target int) int {
|
||||||
|
sum := 0
|
||||||
|
for _, v := range nums {
|
||||||
|
sum += v
|
||||||
|
}
|
||||||
|
if math.Abs(float64(target)) > float64(sum) {
|
||||||
|
return 0 // 此时没有方案
|
||||||
|
}
|
||||||
|
if (target + sum) % 2 == 1 {
|
||||||
|
return 0 // 此时没有方案
|
||||||
|
}
|
||||||
|
bagSize := (target + sum) / 2
|
||||||
|
|
||||||
|
dp := make([][]int, len(nums))
|
||||||
|
for i := range dp {
|
||||||
|
dp[i] = make([]int, bagSize + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化最上行
|
||||||
|
if nums[0] <= bagSize {
|
||||||
|
dp[0][nums[0]] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化最左列,最左列其他数值在递推公式中就完成了赋值
|
||||||
|
dp[0][0] = 1
|
||||||
|
|
||||||
|
var numZero float64
|
||||||
|
for i := range nums {
|
||||||
|
if nums[i] == 0 {
|
||||||
|
numZero++
|
||||||
|
}
|
||||||
|
dp[i][0] = int(math.Pow(2, numZero))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 以下遍历顺序行列可以颠倒
|
||||||
|
for i := 1; i < len(nums); i++ { // 行,遍历物品
|
||||||
|
for j := 0; j <= bagSize; j++ { // 列,遍历背包
|
||||||
|
if nums[i] > j {
|
||||||
|
dp[i][j] = dp[i-1][j]
|
||||||
|
} else {
|
||||||
|
dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[len(nums)-1][bagSize]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
一维dp
|
||||||
```go
|
```go
|
||||||
func findTargetSumWays(nums []int, target int) int {
|
func findTargetSumWays(nums []int, target int) int {
|
||||||
sum := 0
|
sum := 0
|
||||||
|
@ -288,6 +288,7 @@ class Solution:
|
|||||||
|
|
||||||
### Go:
|
### Go:
|
||||||
|
|
||||||
|
一维dp
|
||||||
```go
|
```go
|
||||||
func change(amount int, coins []int) int {
|
func change(amount int, coins []int) int {
|
||||||
// 定义dp数组
|
// 定义dp数组
|
||||||
@ -306,6 +307,29 @@ func change(amount int, coins []int) int {
|
|||||||
return dp[amount]
|
return dp[amount]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
二维dp
|
||||||
|
```go
|
||||||
|
func change(amount int, coins []int) int {
|
||||||
|
dp := make([][]int, len(coins))
|
||||||
|
for i := range dp {
|
||||||
|
dp[i] = make([]int, amount + 1)
|
||||||
|
dp[i][0] = 1
|
||||||
|
}
|
||||||
|
for j := coins[0]; j <= amount; j++ {
|
||||||
|
dp[0][j] += dp[0][j-coins[0]]
|
||||||
|
}
|
||||||
|
for i := 1; i < len(coins); i++ {
|
||||||
|
for j := 1; j <= amount; j++ {
|
||||||
|
if j < coins[i] {
|
||||||
|
dp[i][j] = dp[i-1][j]
|
||||||
|
} else {
|
||||||
|
dp[i][j] = dp[i][j-coins[i]] + dp[i-1][j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[len(coins)-1][amount]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Rust:
|
### Rust:
|
||||||
|
|
||||||
|
@ -492,6 +492,25 @@ int findLengthOfLCIS(int* nums, int numsSize) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Cangjie
|
||||||
|
|
||||||
|
```cangjie
|
||||||
|
func findLengthOfLCIS(nums: Array<Int64>): Int64 {
|
||||||
|
let n = nums.size
|
||||||
|
if (n <= 1) {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
let dp = Array(n, repeat: 1)
|
||||||
|
var res = 0
|
||||||
|
for (i in 1..n) {
|
||||||
|
if (nums[i] > nums[i - 1]) {
|
||||||
|
dp[i] = dp[i - 1] + 1
|
||||||
|
}
|
||||||
|
res = max(res, dp[i])
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -581,6 +581,25 @@ int findLength(int* nums1, int nums1Size, int* nums2, int nums2Size) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Cangjie
|
||||||
|
|
||||||
|
```cangjie
|
||||||
|
func findLength(nums1: Array<Int64>, nums2: Array<Int64>): Int64 {
|
||||||
|
let n = nums1.size
|
||||||
|
let m = nums2.size
|
||||||
|
let dp = Array(n + 1, {_ => Array(m + 1, item: 0)})
|
||||||
|
var res = 0
|
||||||
|
for (i in 1..=n) {
|
||||||
|
for (j in 1..=m) {
|
||||||
|
if (nums1[i - 1] == nums2[j - 1]) {
|
||||||
|
dp[i][j] = dp[i - 1][j - 1] + 1
|
||||||
|
}
|
||||||
|
res = max(res, dp[i][j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -399,6 +399,25 @@ int longestCommonSubsequence(char* text1, char* text2) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Cangjie
|
||||||
|
|
||||||
|
```cangjie
|
||||||
|
func longestCommonSubsequence(text1: String, text2: String): Int64 {
|
||||||
|
let n = text1.size
|
||||||
|
let m = text2.size
|
||||||
|
let dp = Array(n + 1, {_ => Array(m + 1, repeat: 0)})
|
||||||
|
for (i in 1..=n) {
|
||||||
|
for (j in 1..=m) {
|
||||||
|
if (text1[i - 1] == text2[j - 1]) {
|
||||||
|
dp[i][j] = dp[i - 1][j - 1] + 1
|
||||||
|
} else {
|
||||||
|
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[n][m]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
@ -549,6 +549,62 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
### Javascript
|
### Javascript
|
||||||
|
|
||||||
|
```js
|
||||||
|
function kruskal(v, edges) {
|
||||||
|
const father = Array.from({ length: v + 1 }, (_, i) => i)
|
||||||
|
|
||||||
|
function find(u){
|
||||||
|
if (u === father[u]) {
|
||||||
|
return u
|
||||||
|
} else {
|
||||||
|
father[u] = find(father[u])
|
||||||
|
return father[u]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSame(u, v) {
|
||||||
|
let s = find(u)
|
||||||
|
let t = find(v)
|
||||||
|
return s === t
|
||||||
|
}
|
||||||
|
|
||||||
|
function join(u, v) {
|
||||||
|
let s = find(u)
|
||||||
|
let t = find(v)
|
||||||
|
if (s !== t) {
|
||||||
|
father[s] = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
edges.sort((a, b) => a[2] - b[2])
|
||||||
|
let result = 0
|
||||||
|
for (const [v1, v2, w] of edges) {
|
||||||
|
if (!isSame(v1, v2)) {
|
||||||
|
result += w
|
||||||
|
join(v1 ,v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const rl = require('readline').createInterface({ input: process.stdin })
|
||||||
|
const iter = rl[Symbol.asyncIterator]()
|
||||||
|
const readline = async () => (await iter.next()).value
|
||||||
|
const [v, e] = (await readline()).split(" ").map(Number)
|
||||||
|
const edges = []
|
||||||
|
for (let i = 0 ; i < e ; i++) {
|
||||||
|
edges.push((await readline()).split(" ").map(Number))
|
||||||
|
}
|
||||||
|
kruskal(v, edges)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
### TypeScript
|
### TypeScript
|
||||||
|
|
||||||
### PhP
|
### PhP
|
||||||
|
@ -693,6 +693,55 @@ if __name__ == "__main__":
|
|||||||
### Rust
|
### Rust
|
||||||
|
|
||||||
### Javascript
|
### Javascript
|
||||||
|
```js
|
||||||
|
function prim(v, edges) {
|
||||||
|
const grid = Array.from({ length: v + 1 }, () => new Array(v + 1).fill(10001)); // Fixed grid initialization
|
||||||
|
const minDist = new Array(v + 1).fill(10001)
|
||||||
|
const isInTree = new Array(v + 1).fill(false)
|
||||||
|
// 建構鄰接矩陣
|
||||||
|
for(const [v1, v2, w] of edges) {
|
||||||
|
grid[v1][v2] = w
|
||||||
|
grid[v2][v1] = w
|
||||||
|
}
|
||||||
|
// prim 演算法
|
||||||
|
for (let i = 1 ; i < v ; i++) {
|
||||||
|
let cur = -1
|
||||||
|
let tempMinDist = Number.MAX_VALUE
|
||||||
|
// 1. 尋找距離生成樹最近的節點
|
||||||
|
for (let j = 1 ; j < v + 1 ; j++) {
|
||||||
|
if (!isInTree[j] && minDist[j] < tempMinDist) {
|
||||||
|
tempMinDist = minDist[j]
|
||||||
|
cur = j
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2. 將節點放入生成樹
|
||||||
|
isInTree[cur] = true
|
||||||
|
// 3. 更新非生成樹節點與生成樹的最短距離
|
||||||
|
for (let j = 1 ; j < v + 1 ; j++) {
|
||||||
|
if (!isInTree[j] && grid[cur][j] < minDist[j]) {
|
||||||
|
minDist[j] = grid[cur][j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(minDist.slice(2).reduce((acc, cur) => acc + cur, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const rl = require('readline').createInterface({ input: process.stdin })
|
||||||
|
const iter = rl[Symbol.asyncIterator]()
|
||||||
|
const readline = async () => (await iter.next()).value
|
||||||
|
const [v, e] = (await readline()).split(" ").map(Number)
|
||||||
|
const edges = []
|
||||||
|
for (let i = 0 ; i < e ; i++) {
|
||||||
|
edges.push((await readline()).split(" ").map(Number))
|
||||||
|
}
|
||||||
|
prim(v, edges)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
||||||
|
```
|
||||||
|
|
||||||
### TypeScript
|
### TypeScript
|
||||||
|
|
||||||
|
@ -480,7 +480,84 @@ const bfs = (graph, visited, x, y) => {
|
|||||||
})()
|
})()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```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 dfs = (graph, visited, x, y) => {
|
||||||
|
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){
|
||||||
|
count++
|
||||||
|
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) { //遇到没有访问过的陆地
|
||||||
|
// 重新计算面积
|
||||||
|
count = 1
|
||||||
|
visited[i][j] = true
|
||||||
|
|
||||||
|
// 深度优先遍历,统计岛屿内节点数,并将岛屿标记为已访问
|
||||||
|
dfs(graph, visited, i, j)
|
||||||
|
|
||||||
|
// 更新最大岛屿面积
|
||||||
|
result = Math.max(result, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(result);
|
||||||
|
})()
|
||||||
|
```
|
||||||
|
|
||||||
### TypeScript
|
### TypeScript
|
||||||
|
|
||||||
|
@ -307,6 +307,71 @@ for i in range(n):
|
|||||||
|
|
||||||
print(count)
|
print(count)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
direction = [[1, 0], [-1, 0], [0, 1], [0, -1]]
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
# 深度搜尋
|
||||||
|
def dfs(grid, y, x):
|
||||||
|
grid[y][x] = 0
|
||||||
|
global result
|
||||||
|
result += 1
|
||||||
|
|
||||||
|
for i, j in direction:
|
||||||
|
next_x = x + j
|
||||||
|
next_y = y + i
|
||||||
|
if (next_x < 0 or next_y < 0 or
|
||||||
|
next_x >= len(grid[0]) or next_y >= len(grid)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
if grid[next_y][next_x] == 1 and not visited[next_y][next_x]:
|
||||||
|
visited[next_y][next_x] = True
|
||||||
|
dfs(grid, next_y, next_x)
|
||||||
|
|
||||||
|
|
||||||
|
# 讀取輸入值
|
||||||
|
n, m = map(int, input().split())
|
||||||
|
grid = []
|
||||||
|
visited = [[False] * m for _ in range(n)]
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
grid.append(list(map(int, input().split())))
|
||||||
|
|
||||||
|
# 處理邊界
|
||||||
|
for j in range(m):
|
||||||
|
# 上邊界
|
||||||
|
if grid[0][j] == 1 and not visited[0][j]:
|
||||||
|
visited[0][j] = True
|
||||||
|
dfs(grid, 0, j)
|
||||||
|
# 下邊界
|
||||||
|
if grid[n - 1][j] == 1 and not visited[n - 1][j]:
|
||||||
|
visited[n - 1][j] = True
|
||||||
|
dfs(grid, n - 1, j)
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
# 左邊界
|
||||||
|
if grid[i][0] == 1 and not visited[i][0]:
|
||||||
|
visited[i][0] = True
|
||||||
|
dfs(grid, i, 0)
|
||||||
|
# 右邊界
|
||||||
|
if grid[i][m - 1] == 1 and not visited[i][m - 1]:
|
||||||
|
visited[i][m - 1] = True
|
||||||
|
dfs(grid, i, m - 1)
|
||||||
|
|
||||||
|
# 計算孤島總面積
|
||||||
|
result = 0 # 初始化,避免使用到處理邊界時所產生的累加值
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
for j in range(m):
|
||||||
|
if grid[i][j] == 1 and not visited[i][j]:
|
||||||
|
visited[i][j] = True
|
||||||
|
dfs(grid, i, j)
|
||||||
|
|
||||||
|
# 輸出孤島的總面積
|
||||||
|
print(result)
|
||||||
|
```
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
|
@ -178,6 +178,45 @@ int main() {
|
|||||||
|
|
||||||
### Python
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
father = list()
|
||||||
|
|
||||||
|
def find(u):
|
||||||
|
if u == father[u]:
|
||||||
|
return u
|
||||||
|
else:
|
||||||
|
father[u] = find(father[u])
|
||||||
|
return father[u]
|
||||||
|
|
||||||
|
def is_same(u, v):
|
||||||
|
u = find(u)
|
||||||
|
v = find(v)
|
||||||
|
return u == v
|
||||||
|
|
||||||
|
def join(u, v):
|
||||||
|
u = find(u)
|
||||||
|
v = find(v)
|
||||||
|
if u != v:
|
||||||
|
father[u] = v
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 輸入
|
||||||
|
n = int(input())
|
||||||
|
for i in range(n + 1):
|
||||||
|
father.append(i)
|
||||||
|
# 尋找冗余邊
|
||||||
|
result = None
|
||||||
|
for i in range(n):
|
||||||
|
s, t = map(int, input().split())
|
||||||
|
if is_same(s, t):
|
||||||
|
result = str(s) + ' ' + str(t)
|
||||||
|
else:
|
||||||
|
join(s, t)
|
||||||
|
|
||||||
|
# 輸出
|
||||||
|
print(result)
|
||||||
|
```
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
|
|
||||||
### Rust
|
### Rust
|
||||||
|
@ -250,9 +250,193 @@ int main() {
|
|||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
### Java
|
### Java
|
||||||
|
```java
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
static int n;
|
||||||
|
static int[] father = new int[1001]; // 并查集数组
|
||||||
|
|
||||||
|
// 并查集初始化
|
||||||
|
public static void init() {
|
||||||
|
for (int i = 1; i <= n; ++i) {
|
||||||
|
father[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 并查集里寻根的过程
|
||||||
|
public static int find(int u) {
|
||||||
|
if (u == father[u]) return u;
|
||||||
|
return father[u] = find(father[u]); // 路径压缩
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 v->u 这条边加入并查集
|
||||||
|
public static void join(int u, int v) {
|
||||||
|
u = find(u);
|
||||||
|
v = find(v);
|
||||||
|
if (u != v) {
|
||||||
|
father[v] = u; // 合并两棵树
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断 u 和 v 是否有同一个根
|
||||||
|
public static boolean same(int u, int v) {
|
||||||
|
return find(u) == find(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在有向图里找到删除的那条边,使其变成树
|
||||||
|
public static void getRemoveEdge(List<int[]> edges) {
|
||||||
|
init(); // 初始化并查集
|
||||||
|
for (int i = 0; i < n; i++) { // 遍历所有的边
|
||||||
|
if (same(edges.get(i)[0], edges.get(i)[1])) { // 如果构成有向环了,就是要删除的边
|
||||||
|
System.out.println(edges.get(i)[0] + " " + edges.get(i)[1]);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
join(edges.get(i)[0], edges.get(i)[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删一条边之后判断是不是树
|
||||||
|
public static boolean isTreeAfterRemoveEdge(List<int[]> edges, int deleteEdge) {
|
||||||
|
init(); // 初始化并查集
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (i == deleteEdge) continue;
|
||||||
|
if (same(edges.get(i)[0], edges.get(i)[1])) { // 如果构成有向环了,一定不是树
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
join(edges.get(i)[0], edges.get(i)[1]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Scanner sc = new Scanner(System.in);
|
||||||
|
List<int[]> edges = new ArrayList<>(); // 存储所有的边
|
||||||
|
|
||||||
|
n = sc.nextInt(); // 顶点数
|
||||||
|
int[] inDegree = new int[n + 1]; // 记录每个节点的入度
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
int s = sc.nextInt(); // 边的起点
|
||||||
|
int t = sc.nextInt(); // 边的终点
|
||||||
|
inDegree[t]++;
|
||||||
|
edges.add(new int[]{s, t}); // 将边加入列表
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> vec = new ArrayList<>(); // 记录入度为2的边(如果有的话就两条边)
|
||||||
|
// 找入度为2的节点所对应的边,注意要倒序,因为优先删除最后出现的一条边
|
||||||
|
for (int i = n - 1; i >= 0; i--) {
|
||||||
|
if (inDegree[edges.get(i)[1]] == 2) {
|
||||||
|
vec.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 情况一、情况二
|
||||||
|
if (vec.size() > 0) {
|
||||||
|
// vec里的边已经按照倒叙放的,所以优先删 vec.get(0) 这条边
|
||||||
|
if (isTreeAfterRemoveEdge(edges, vec.get(0))) {
|
||||||
|
System.out.println(edges.get(vec.get(0))[0] + " " + edges.get(vec.get(0))[1]);
|
||||||
|
} else {
|
||||||
|
System.out.println(edges.get(vec.get(1))[0] + " " + edges.get(vec.get(1))[1]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理情况三:明确没有入度为2的情况,一定有有向环,找到构成环的边返回即可
|
||||||
|
getRemoveEdge(edges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
### Python
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
father = list()
|
||||||
|
|
||||||
|
|
||||||
|
def find(u):
|
||||||
|
if u == father[u]:
|
||||||
|
return u
|
||||||
|
else:
|
||||||
|
father[u] = find(father[u])
|
||||||
|
return father[u]
|
||||||
|
|
||||||
|
|
||||||
|
def is_same(u, v):
|
||||||
|
u = find(u)
|
||||||
|
v = find(v)
|
||||||
|
return u == v
|
||||||
|
|
||||||
|
|
||||||
|
def join(u, v):
|
||||||
|
u = find(u)
|
||||||
|
v = find(v)
|
||||||
|
if u != v:
|
||||||
|
father[u] = v
|
||||||
|
|
||||||
|
|
||||||
|
def is_tree_after_remove_edge(edges, edge, n):
|
||||||
|
# 初始化并查集
|
||||||
|
global father
|
||||||
|
father = [i for i in range(n + 1)]
|
||||||
|
|
||||||
|
for i in range(len(edges)):
|
||||||
|
if i == edge:
|
||||||
|
continue
|
||||||
|
s, t = edges[i]
|
||||||
|
if is_same(s, t): # 成環,即不是有向樹
|
||||||
|
return False
|
||||||
|
else: # 將s,t放入集合中
|
||||||
|
join(s, t)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_remove_edge(edges):
|
||||||
|
# 初始化并查集
|
||||||
|
global father
|
||||||
|
father = [i for i in range(n + 1)]
|
||||||
|
|
||||||
|
for s, t in edges:
|
||||||
|
if is_same(s, t):
|
||||||
|
print(s, t)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
join(s, t)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 輸入
|
||||||
|
n = int(input())
|
||||||
|
edges = list()
|
||||||
|
in_degree = defaultdict(int)
|
||||||
|
|
||||||
|
for i in range(n):
|
||||||
|
s, t = map(int, input().split())
|
||||||
|
in_degree[t] += 1
|
||||||
|
edges.append([s, t])
|
||||||
|
|
||||||
|
# 尋找入度為2的邊,並紀錄其下標(index)
|
||||||
|
vec = list()
|
||||||
|
for i in range(n - 1, -1, -1):
|
||||||
|
if in_degree[edges[i][1]] == 2:
|
||||||
|
vec.append(i)
|
||||||
|
|
||||||
|
# 輸出
|
||||||
|
if len(vec) > 0:
|
||||||
|
# 情況一:刪除輸出順序靠後的邊
|
||||||
|
if is_tree_after_remove_edge(edges, vec[0], n):
|
||||||
|
print(edges[vec[0]][0], edges[vec[0]][1])
|
||||||
|
# 情況二:只能刪除特定的邊
|
||||||
|
else:
|
||||||
|
print(edges[vec[1]][0], edges[vec[1]][1])
|
||||||
|
else:
|
||||||
|
# 情況三: 原圖有環
|
||||||
|
get_remove_edge(edges)
|
||||||
|
```
|
||||||
|
|
||||||
### Go
|
### Go
|
||||||
|
|
||||||
### Rust
|
### Rust
|
||||||
|
Reference in New Issue
Block a user