mirror of
https://gitlab.com/game-loader/hugo.git
synced 2025-04-20 05:52:07 +08:00
leetcode update
This commit is contained in:
parent
19b03cbffe
commit
f20116d0cf
@ -3836,3 +3836,125 @@ func findFarmland(land [][]int) [][]int {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## day54 2024-04-21
|
||||||
|
|
||||||
|
### 1971. Find if Path Exists in Graph
|
||||||
|
|
||||||
|
There is a bi-directional graph with n vertices, where each vertex is labeled from 0 to n - 1 (inclusive). The edges in the graph are represented as a 2D integer array edges, where each edges[i] = [ui, vi] denotes a bi-directional edge between vertex ui and vertex vi. Every vertex pair is connected by at most one edge, and no vertex has an edge to itself.
|
||||||
|
|
||||||
|
You want to determine if there is a valid path that exists from vertex source to vertex destination.
|
||||||
|
|
||||||
|
Given edges and the integers n, source, and destination, return true if there is a valid path from source to destination, or false otherwise.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 题解
|
||||||
|
|
||||||
|
本题使用并查集即可快速解决, 因为若两个节点连通, 两个节点必定位于同一个连通图中, 而每个连通图可以通过并查集使用一个节点的值来表示, 因此遍历所有边并构造并查集, 最终比较源点和目标点所在的并查集的代表元(即用来代表一个连通图的节点的值)是否相同即可确定是否有通路.
|
||||||
|
|
||||||
|
### 代码
|
||||||
|
|
||||||
|
```go
|
||||||
|
func validPath(n int, edges [][]int, source int, destination int) bool {
|
||||||
|
querymap := map[int]int{}
|
||||||
|
querymap[source] = source
|
||||||
|
querymap[destination] = destination
|
||||||
|
for _,edge := range edges{
|
||||||
|
value,exist := querymap[edge[0]]
|
||||||
|
value2,exist2 := querymap[edge[1]]
|
||||||
|
if !exist && !exist2{
|
||||||
|
querymap[edge[0]] = edge[0]
|
||||||
|
querymap[edge[1]] = edge[0]
|
||||||
|
}else if exist && !exist2{
|
||||||
|
querymap[edge[1]] = value
|
||||||
|
}else if !exist && exist2{
|
||||||
|
querymap[edge[0]] = value2
|
||||||
|
}else{
|
||||||
|
for querymap[value] != value{
|
||||||
|
value = querymap[value]
|
||||||
|
}
|
||||||
|
for querymap[value2] != value2{
|
||||||
|
value2 = querymap[value2]
|
||||||
|
}
|
||||||
|
if value != value2{
|
||||||
|
querymap[value2] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for querymap[source] != source{
|
||||||
|
source = querymap[source]
|
||||||
|
}
|
||||||
|
for querymap[destination] != destination{
|
||||||
|
destination = querymap[destination]
|
||||||
|
}
|
||||||
|
if source != destination{
|
||||||
|
return false
|
||||||
|
}else{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 总结
|
||||||
|
|
||||||
|
最快的解法同样使用了并查集, 不过将并查集的操作都单独写成了对应的函数. 同时使用了数组来保存集合中某个元素的父元素是什么, 数组下标表示某个节点, 对应的值表示其父节点的值. 这样查询速度更快, 不过浪费了一些空间.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type DisjointSet struct {
|
||||||
|
roots []int
|
||||||
|
ranks []int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DisjointSet) Find(x int) int {
|
||||||
|
if ds.roots[x] == x {
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
ds.roots[x] = ds.Find(ds.roots[x])
|
||||||
|
return ds.roots[x]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DisjointSet) Union(x, y int) {
|
||||||
|
rootX := ds.Find(x)
|
||||||
|
rootY := ds.Find(y)
|
||||||
|
if rootX == rootY {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rankX := ds.ranks[rootX]
|
||||||
|
rankY := ds.ranks[rootY]
|
||||||
|
if rankX > rankY {
|
||||||
|
ds.roots[rootY] = rootX
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if rankX < rankY {
|
||||||
|
ds.roots[rootX] = rootY
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ds.roots[rootX] = rootY
|
||||||
|
ds.ranks[rootY] += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds *DisjointSet) IsConnected(x, y int) bool {
|
||||||
|
return ds.Find(x) == ds.Find(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDisjointSet(n int) *DisjointSet {
|
||||||
|
roots := make([]int, n)
|
||||||
|
ranks := make([]int, n)
|
||||||
|
for i := range n {
|
||||||
|
roots[i] = i
|
||||||
|
ranks[i] = 1
|
||||||
|
}
|
||||||
|
newDisjointSet := DisjointSet{roots, ranks}
|
||||||
|
return &newDisjointSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func validPath(n int, edges [][]int, source int, destination int) bool {
|
||||||
|
ds := newDisjointSet(n)
|
||||||
|
for _, edge := range edges {
|
||||||
|
ds.Union(edge[0], edge[1])
|
||||||
|
}
|
||||||
|
return ds.IsConnected(source, destination)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user