mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-05 00:25:22 +08:00
使用并查集模板
This commit is contained in:
@ -1,5 +1,9 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
// 解法一 map,时间复杂度 O(n)
|
||||
func longestConsecutive(nums []int) int {
|
||||
res, numMap := 0, map[int]int{}
|
||||
@ -37,8 +41,8 @@ func longestConsecutive1(nums []int) int {
|
||||
if len(nums) == 0 {
|
||||
return 0
|
||||
}
|
||||
numMap, countMap, lcs, uf := map[int]int{}, map[int]int{}, 0, UnionFind{}
|
||||
uf.init(len(nums))
|
||||
numMap, countMap, lcs, uf := map[int]int{}, map[int]int{}, 0, template.UnionFind{}
|
||||
uf.Init(len(nums))
|
||||
for i := 0; i < len(nums); i++ {
|
||||
countMap[i] = 1
|
||||
}
|
||||
@ -48,14 +52,14 @@ func longestConsecutive1(nums []int) int {
|
||||
}
|
||||
numMap[nums[i]] = i
|
||||
if _, ok := numMap[nums[i]+1]; ok {
|
||||
uf.union(i, numMap[nums[i]+1])
|
||||
uf.Union(i, numMap[nums[i]+1])
|
||||
}
|
||||
if _, ok := numMap[nums[i]-1]; ok {
|
||||
uf.union(i, numMap[nums[i]-1])
|
||||
uf.Union(i, numMap[nums[i]-1])
|
||||
}
|
||||
}
|
||||
for key := range countMap {
|
||||
parent := uf.find(key)
|
||||
parent := uf.Find(key)
|
||||
if parent != key {
|
||||
countMap[parent]++
|
||||
}
|
||||
|
@ -1,30 +1,34 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
// 解法一 并查集
|
||||
func solve(board [][]byte) {
|
||||
if len(board) == 0 {
|
||||
return
|
||||
}
|
||||
m, n := len(board[0]), len(board)
|
||||
uf := UnionFind{}
|
||||
uf.init(n*m + 1) // 特意多一个特殊点用来标记
|
||||
uf := template.UnionFind{}
|
||||
uf.Init(n*m + 1) // 特意多一个特殊点用来标记
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < m; j++ {
|
||||
if (i == 0 || i == n-1 || j == 0 || j == m-1) && board[i][j] == 'O' { //棋盘边缘上的 'O' 点
|
||||
uf.union(i*m+j, n*m)
|
||||
uf.Union(i*m+j, n*m)
|
||||
} else if board[i][j] == 'O' { //棋盘非边缘上的内部的 'O' 点
|
||||
if board[i-1][j] == 'O' {
|
||||
uf.union(i*m+j, (i-1)*m+j)
|
||||
uf.Union(i*m+j, (i-1)*m+j)
|
||||
}
|
||||
if board[i+1][j] == 'O' {
|
||||
uf.union(i*m+j, (i+1)*m+j)
|
||||
uf.Union(i*m+j, (i+1)*m+j)
|
||||
}
|
||||
if board[i][j-1] == 'O' {
|
||||
uf.union(i*m+j, i*m+j-1)
|
||||
uf.Union(i*m+j, i*m+j-1)
|
||||
}
|
||||
if board[i][j+1] == 'O' {
|
||||
uf.union(i*m+j, i*m+j+1)
|
||||
uf.Union(i*m+j, i*m+j+1)
|
||||
}
|
||||
|
||||
}
|
||||
@ -32,7 +36,7 @@ func solve(board [][]byte) {
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < m; j++ {
|
||||
if uf.find(i*m+j) != uf.find(n*m) {
|
||||
if uf.Find(i*m+j) != uf.Find(n*m) {
|
||||
board[i][j] = 'X'
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ package leetcode
|
||||
* }
|
||||
*/
|
||||
|
||||
// 解法一
|
||||
// 解法一 递归
|
||||
func preorderTraversal(root *TreeNode) []int {
|
||||
res := []int{}
|
||||
if root != nil {
|
||||
@ -26,7 +26,7 @@ func preorderTraversal(root *TreeNode) []int {
|
||||
return res
|
||||
}
|
||||
|
||||
// 解法二
|
||||
// 解法二 递归
|
||||
func preorderTraversal1(root *TreeNode) []int {
|
||||
var result []int
|
||||
preorder(root, &result)
|
||||
@ -40,3 +40,26 @@ func preorder(root *TreeNode, output *[]int) {
|
||||
preorder(root.Right, output)
|
||||
}
|
||||
}
|
||||
|
||||
// 解法三 非递归,用栈模拟递归过程
|
||||
func preorderTraversal2(root *TreeNode) []int {
|
||||
if root == nil {
|
||||
return []int{}
|
||||
}
|
||||
stack, res := []*TreeNode{}, []int{}
|
||||
stack = append(stack, root)
|
||||
for len(stack) != 0 {
|
||||
node := stack[len(stack)-1]
|
||||
stack = stack[:len(stack)-1]
|
||||
if node != nil {
|
||||
res = append(res, node.Val)
|
||||
}
|
||||
if node.Right != nil {
|
||||
stack = append(stack, node.Right)
|
||||
}
|
||||
if node.Left != nil {
|
||||
stack = append(stack, node.Left)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
@ -1,72 +1,26 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
// 解法一 并查集
|
||||
|
||||
// UnionFind defind
|
||||
type UnionFind struct {
|
||||
parent, rank []int
|
||||
count int
|
||||
}
|
||||
|
||||
func (uf *UnionFind) init(n int) {
|
||||
uf.count = n
|
||||
uf.parent = make([]int, n)
|
||||
uf.rank = make([]int, n)
|
||||
for i := range uf.parent {
|
||||
uf.parent[i] = i
|
||||
}
|
||||
}
|
||||
|
||||
func (uf *UnionFind) find(p int) int {
|
||||
root := p
|
||||
for root != uf.parent[root] {
|
||||
root = uf.parent[root]
|
||||
}
|
||||
// compress path
|
||||
for p != uf.parent[p] {
|
||||
tmp := uf.parent[p]
|
||||
uf.parent[p] = root
|
||||
p = tmp
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
func (uf *UnionFind) union(p, q int) {
|
||||
proot := uf.find(p)
|
||||
qroot := uf.find(q)
|
||||
if proot == qroot {
|
||||
return
|
||||
}
|
||||
if uf.rank[qroot] > uf.rank[proot] {
|
||||
uf.parent[proot] = qroot
|
||||
} else {
|
||||
uf.parent[qroot] = proot
|
||||
if uf.rank[proot] == uf.rank[qroot] {
|
||||
uf.rank[proot]++
|
||||
}
|
||||
}
|
||||
uf.count--
|
||||
}
|
||||
|
||||
func (uf *UnionFind) totalCount() int {
|
||||
return uf.count
|
||||
}
|
||||
|
||||
func findCircleNum(M [][]int) int {
|
||||
n := len(M)
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
uf := UnionFind{}
|
||||
uf.init(n)
|
||||
uf := template.UnionFind{}
|
||||
uf.Init(n)
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j <= i; j++ {
|
||||
if M[i][j] == 1 {
|
||||
uf.union(i, j)
|
||||
uf.Union(i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
return uf.count
|
||||
return uf.TotalCount()
|
||||
}
|
||||
|
||||
// 解法二 FloodFill DFS 暴力解法
|
||||
|
@ -1,14 +1,18 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func findRedundantConnection(edges [][]int) []int {
|
||||
if len(edges) == 0 {
|
||||
return []int{}
|
||||
}
|
||||
uf, res := UnionFind{}, []int{}
|
||||
uf.init(len(edges) + 1)
|
||||
uf, res := template.UnionFind{}, []int{}
|
||||
uf.Init(len(edges) + 1)
|
||||
for i := 0; i < len(edges); i++ {
|
||||
if uf.find(edges[i][0]) != uf.find(edges[i][1]) {
|
||||
uf.union(edges[i][0], edges[i][1])
|
||||
if uf.Find(edges[i][0]) != uf.Find(edges[i][1]) {
|
||||
uf.Union(edges[i][0], edges[i][1])
|
||||
} else {
|
||||
res = append(res, edges[i][0])
|
||||
res = append(res, edges[i][1])
|
||||
|
@ -1,11 +1,15 @@
|
||||
package leetcode
|
||||
|
||||
import "sort"
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
// 解法一 并查集优化搜索解法
|
||||
func accountsMerge(accounts [][]string) (r [][]string) {
|
||||
uf := UnionFind{}
|
||||
uf.init(len(accounts))
|
||||
uf := template.UnionFind{}
|
||||
uf.Init(len(accounts))
|
||||
// emailToID 将所有的 email 邮箱都拆开,拆开与 id(数组下标) 对应
|
||||
// idToName 将 id(数组下标) 与 name 对应
|
||||
// idToEmails 将 id(数组下标) 与整理好去重以后的 email 组对应
|
||||
@ -15,13 +19,13 @@ func accountsMerge(accounts [][]string) (r [][]string) {
|
||||
for i := 1; i < len(acc); i++ {
|
||||
pid, ok := emailToID[acc[i]]
|
||||
if ok {
|
||||
uf.union(id, pid)
|
||||
uf.Union(id, pid)
|
||||
}
|
||||
emailToID[acc[i]] = id
|
||||
}
|
||||
}
|
||||
for email, id := range emailToID {
|
||||
pid := uf.find(id)
|
||||
pid := uf.Find(id)
|
||||
idToEmails[pid] = append(idToEmails[pid], email)
|
||||
}
|
||||
for id, emails := range idToEmails {
|
||||
@ -37,8 +41,8 @@ func accountsMerge1(accounts [][]string) [][]string {
|
||||
if len(accounts) == 0 {
|
||||
return [][]string{}
|
||||
}
|
||||
uf, res, visited := UnionFind{}, [][]string{}, map[int]bool{}
|
||||
uf.init(len(accounts))
|
||||
uf, res, visited := template.UnionFind{}, [][]string{}, map[int]bool{}
|
||||
uf.Init(len(accounts))
|
||||
for i := 0; i < len(accounts); i++ {
|
||||
for j := i + 1; j < len(accounts); j++ {
|
||||
if accounts[i][0] == accounts[j][0] {
|
||||
@ -55,7 +59,7 @@ func accountsMerge1(accounts [][]string) [][]string {
|
||||
}
|
||||
}
|
||||
if flag {
|
||||
uf.union(i, j)
|
||||
uf.Union(i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,7 +70,7 @@ func accountsMerge1(accounts [][]string) [][]string {
|
||||
}
|
||||
emails, account, tmpMap := accounts[i][1:], []string{accounts[i][0]}, map[string]string{}
|
||||
for j := i + 1; j < len(accounts); j++ {
|
||||
if uf.find(j) == uf.find(i) {
|
||||
if uf.Find(j) == uf.Find(i) {
|
||||
visited[j] = true
|
||||
for _, v := range accounts[j][1:] {
|
||||
tmpMap[v] = v
|
||||
|
@ -1,18 +1,22 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func minSwapsCouples(row []int) int {
|
||||
if len(row)&1 == 1 {
|
||||
return 0
|
||||
}
|
||||
uf := UnionFind{}
|
||||
uf.init(len(row))
|
||||
uf := template.UnionFind{}
|
||||
uf.Init(len(row))
|
||||
for i := 0; i < len(row)-1; i = i + 2 {
|
||||
uf.union(i, i+1)
|
||||
uf.Union(i, i+1)
|
||||
}
|
||||
for i := 0; i < len(row)-1; i = i + 2 {
|
||||
if uf.find(row[i]) != uf.find(row[i+1]) {
|
||||
uf.union(row[i], row[i+1])
|
||||
if uf.Find(row[i]) != uf.Find(row[i+1]) {
|
||||
uf.Union(row[i], row[i+1])
|
||||
}
|
||||
}
|
||||
return len(row)/2 - uf.count
|
||||
return len(row)/2 - uf.TotalCount()
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
// 解法一 DFS + 二分
|
||||
func swimInWater(grid [][]int) int {
|
||||
row, col, flags, minWait, maxWait := len(grid), len(grid[0]), make([][]int, len(grid)), 0, 0
|
||||
@ -40,19 +44,19 @@ func addFlags(grid [][]int, flags [][]int, flag int, row int, col int) {
|
||||
|
||||
// 解法二 并查集(并不是此题的最优解)
|
||||
func swimInWater1(grid [][]int) int {
|
||||
n, uf, res := len(grid), UnionFind{}, 0
|
||||
uf.init(n * n)
|
||||
for uf.find(0) != uf.find(n*n-1) {
|
||||
n, uf, res := len(grid), template.UnionFind{}, 0
|
||||
uf.Init(n * n)
|
||||
for uf.Find(0) != uf.Find(n*n-1) {
|
||||
for i := 0; i < n; i++ {
|
||||
for j := 0; j < n; j++ {
|
||||
if grid[i][j] > res {
|
||||
continue
|
||||
}
|
||||
if i < n-1 && grid[i+1][j] <= res {
|
||||
uf.union(i*n+j, i*n+j+n)
|
||||
uf.Union(i*n+j, i*n+j+n)
|
||||
}
|
||||
if j < n-1 && grid[i][j+1] <= res {
|
||||
uf.union(i*n+j, i*n+j+1)
|
||||
uf.Union(i*n+j, i*n+j+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func hitBricks(grid [][]int, hits [][]int) []int {
|
||||
if len(hits) == 0 {
|
||||
return []int{}
|
||||
}
|
||||
uf, m, n, res, oriCount := UnionFindCount{}, len(grid), len(grid[0]), make([]int, len(hits)), 0
|
||||
uf.init(m*n + 1)
|
||||
uf, m, n, res, oriCount := template.UnionFindCount{}, len(grid), len(grid[0]), make([]int, len(hits)), 0
|
||||
uf.Init(m*n + 1)
|
||||
// 先将要打掉的砖块染色
|
||||
for _, hit := range hits {
|
||||
if grid[hit[0]][hit[1]] == 1 {
|
||||
@ -19,13 +23,13 @@ func hitBricks(grid [][]int, hits [][]int) []int {
|
||||
}
|
||||
}
|
||||
}
|
||||
oriCount = uf.count[uf.find(m*n)]
|
||||
oriCount = uf.Count()[uf.Find(m*n)]
|
||||
for i := len(hits) - 1; i >= 0; i-- {
|
||||
if grid[hits[i][0]][hits[i][1]] == 2 {
|
||||
grid[hits[i][0]][hits[i][1]] = 1
|
||||
getUnionFindFromGrid(grid, hits[i][0], hits[i][1], uf)
|
||||
}
|
||||
nowCount := uf.count[uf.find(m*n)]
|
||||
nowCount := uf.Count()[uf.Find(m*n)]
|
||||
if nowCount-oriCount > 0 {
|
||||
res[i] = nowCount - oriCount - 1
|
||||
} else {
|
||||
@ -40,71 +44,16 @@ func isInGrid(grid [][]int, x, y int) bool {
|
||||
return x >= 0 && x < len(grid) && y >= 0 && y < len(grid[0])
|
||||
}
|
||||
|
||||
func getUnionFindFromGrid(grid [][]int, x, y int, uf UnionFindCount) {
|
||||
func getUnionFindFromGrid(grid [][]int, x, y int, uf template.UnionFindCount) {
|
||||
m, n := len(grid), len(grid[0])
|
||||
if x == 0 {
|
||||
uf.union(m*n, x*n+y)
|
||||
uf.Union(m*n, x*n+y)
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
nx := x + dir[i][0]
|
||||
ny := y + dir[i][1]
|
||||
if isInGrid(grid, nx, ny) && grid[nx][ny] == 1 {
|
||||
uf.union(nx*n+ny, x*n+y)
|
||||
uf.Union(nx*n+ny, x*n+y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UnionFindCount define
|
||||
type UnionFindCount struct {
|
||||
parent, count []int
|
||||
}
|
||||
|
||||
func (uf *UnionFindCount) init(n int) {
|
||||
uf.parent = make([]int, n)
|
||||
uf.count = make([]int, n)
|
||||
for i := range uf.parent {
|
||||
uf.parent[i] = i
|
||||
uf.count[i] = 1
|
||||
}
|
||||
}
|
||||
|
||||
func (uf *UnionFindCount) find(p int) int {
|
||||
root := p
|
||||
for root != uf.parent[root] {
|
||||
root = uf.parent[root]
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
// 不进行秩压缩,时间复杂度爆炸,太高了
|
||||
// func (uf *UnionFindCount) union(p, q int) {
|
||||
// proot := uf.find(p)
|
||||
// qroot := uf.find(q)
|
||||
// if proot == qroot {
|
||||
// return
|
||||
// }
|
||||
// if proot != qroot {
|
||||
// uf.parent[proot] = qroot
|
||||
// uf.count[qroot] += uf.count[proot]
|
||||
// }
|
||||
// }
|
||||
|
||||
func (uf *UnionFindCount) union(p, q int) {
|
||||
proot := uf.find(p)
|
||||
qroot := uf.find(q)
|
||||
if proot == qroot {
|
||||
return
|
||||
}
|
||||
if proot == len(uf.parent)-1 {
|
||||
//proot is root
|
||||
} else if qroot == len(uf.parent)-1 {
|
||||
// qroot is root, always attach to root
|
||||
proot, qroot = qroot, proot
|
||||
} else if uf.count[qroot] > uf.count[proot] {
|
||||
proot, qroot = qroot, proot
|
||||
}
|
||||
|
||||
//set relation[0] as parent
|
||||
uf.parent[qroot] = proot
|
||||
uf.count[proot] += uf.count[qroot]
|
||||
}
|
||||
|
@ -1,16 +1,20 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func numSimilarGroups(A []string) int {
|
||||
uf := UnionFind{}
|
||||
uf.init(len(A))
|
||||
uf := template.UnionFind{}
|
||||
uf.Init(len(A))
|
||||
for i := 0; i < len(A); i++ {
|
||||
for j := i + 1; j < len(A); j++ {
|
||||
if isSimilar(A[i], A[j]) {
|
||||
uf.union(i, j)
|
||||
uf.Union(i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
return uf.totalCount()
|
||||
return uf.TotalCount()
|
||||
}
|
||||
|
||||
func isSimilar(a, b string) bool {
|
||||
|
@ -1,28 +1,32 @@
|
||||
package leetcode
|
||||
|
||||
import "math"
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func minMalwareSpread(graph [][]int, initial []int) int {
|
||||
if len(initial) == 0 {
|
||||
return 0
|
||||
}
|
||||
uf, minIndex, count, countMap := UnionFind{}, 0, math.MinInt64, map[int]int{}
|
||||
uf.init(len(graph))
|
||||
uf, minIndex, count, countMap := template.UnionFind{}, 0, math.MinInt64, map[int]int{}
|
||||
uf.Init(len(graph))
|
||||
for i := range graph {
|
||||
for j := range graph[i] {
|
||||
if i == j {
|
||||
break
|
||||
}
|
||||
if graph[i][j] == 1 {
|
||||
uf.union(i, j)
|
||||
uf.Union(i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(graph); i++ {
|
||||
countMap[uf.find(i)]++
|
||||
countMap[uf.Find(i)]++
|
||||
}
|
||||
for _, v := range initial {
|
||||
tmp := countMap[uf.find(v)]
|
||||
tmp := countMap[uf.Find(v)]
|
||||
if count == tmp && minIndex > v {
|
||||
minIndex = v
|
||||
}
|
||||
|
@ -1,34 +1,38 @@
|
||||
package leetcode
|
||||
|
||||
import "math"
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func minMalwareSpread2(graph [][]int, initial []int) int {
|
||||
if len(initial) == 0 {
|
||||
return 0
|
||||
}
|
||||
uf, minIndex, count, countMap, malwareMap, infectMap := UnionFind{}, initial[0], math.MinInt64, map[int]int{}, map[int]int{}, map[int]map[int]int{}
|
||||
uf, minIndex, count, countMap, malwareMap, infectMap := template.UnionFind{}, initial[0], math.MinInt64, map[int]int{}, map[int]int{}, map[int]map[int]int{}
|
||||
for _, v := range initial {
|
||||
malwareMap[v]++
|
||||
}
|
||||
uf.init(len(graph))
|
||||
uf.Init(len(graph))
|
||||
for i := range graph {
|
||||
for j := range graph[i] {
|
||||
if i == j {
|
||||
break
|
||||
}
|
||||
if graph[i][j] == 1 && malwareMap[i] == 0 && malwareMap[j] == 0 {
|
||||
uf.union(i, j)
|
||||
uf.Union(i, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(graph); i++ {
|
||||
countMap[uf.find(i)]++
|
||||
countMap[uf.Find(i)]++
|
||||
}
|
||||
// 记录每个集合和直接相邻病毒节点的个数
|
||||
for _, i := range initial {
|
||||
for j := 0; j < len(graph); j++ {
|
||||
if malwareMap[j] == 0 && graph[i][j] == 1 {
|
||||
p := uf.find(j)
|
||||
p := uf.Find(j)
|
||||
if _, ok := infectMap[p]; ok {
|
||||
infectMap[p][i] = i
|
||||
} else {
|
||||
@ -46,7 +50,7 @@ func minMalwareSpread2(graph [][]int, initial []int) int {
|
||||
for i, v := range infectMap {
|
||||
// 找出只和一个病毒节点相连通的
|
||||
if len(v) == 1 {
|
||||
tmp := countMap[uf.find(i)]
|
||||
tmp := countMap[uf.Find(i)]
|
||||
keys := []int{}
|
||||
for k := range v {
|
||||
keys = append(keys, k)
|
||||
|
@ -1,22 +1,26 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func removeStones(stones [][]int) int {
|
||||
if len(stones) <= 1 {
|
||||
return 0
|
||||
}
|
||||
uf, rowMap, colMap := UnionFind{}, map[int]int{}, map[int]int{}
|
||||
uf.init(len(stones))
|
||||
uf, rowMap, colMap := template.UnionFind{}, map[int]int{}, map[int]int{}
|
||||
uf.Init(len(stones))
|
||||
for i := 0; i < len(stones); i++ {
|
||||
if _, ok := rowMap[stones[i][0]]; ok {
|
||||
uf.union(rowMap[stones[i][0]], i)
|
||||
uf.Union(rowMap[stones[i][0]], i)
|
||||
} else {
|
||||
rowMap[stones[i][0]] = i
|
||||
}
|
||||
if _, ok := colMap[stones[i][1]]; ok {
|
||||
uf.union(colMap[stones[i][1]], i)
|
||||
uf.Union(colMap[stones[i][1]], i)
|
||||
} else {
|
||||
colMap[stones[i][1]] = i
|
||||
}
|
||||
}
|
||||
return len(stones) - uf.totalCount()
|
||||
return len(stones) - uf.TotalCount()
|
||||
}
|
||||
|
@ -1,51 +1,55 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
// 解法一 并查集 UnionFind
|
||||
func largestComponentSize(A []int) int {
|
||||
maxElement, uf, countMap, res := 0, UnionFind{}, map[int]int{}, 1
|
||||
maxElement, uf, countMap, res := 0, template.UnionFind{}, map[int]int{}, 1
|
||||
for _, v := range A {
|
||||
maxElement = max(maxElement, v)
|
||||
}
|
||||
uf.init(maxElement + 1)
|
||||
uf.Init(maxElement + 1)
|
||||
for _, v := range A {
|
||||
for k := 2; k*k <= v; k++ {
|
||||
if v%k == 0 {
|
||||
uf.union(v, k)
|
||||
uf.union(v, v/k)
|
||||
uf.Union(v, k)
|
||||
uf.Union(v, v/k)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, v := range A {
|
||||
countMap[uf.find(v)]++
|
||||
res = max(res, countMap[uf.find(v)])
|
||||
countMap[uf.Find(v)]++
|
||||
res = max(res, countMap[uf.Find(v)])
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// 解法二 UnionFindCount
|
||||
func largestComponentSize1(A []int) int {
|
||||
uf, factorMap := UnionFindCount{}, map[int]int{}
|
||||
uf.init(len(A))
|
||||
uf, factorMap := template.UnionFindCount{}, map[int]int{}
|
||||
uf.Init(len(A))
|
||||
for i, v := range A {
|
||||
for k := 2; k*k <= v; k++ {
|
||||
if v%k == 0 {
|
||||
if _, ok := factorMap[k]; !ok {
|
||||
factorMap[k] = i
|
||||
} else {
|
||||
uf.union(i, factorMap[k])
|
||||
uf.Union(i, factorMap[k])
|
||||
}
|
||||
if _, ok := factorMap[v/k]; !ok {
|
||||
factorMap[v/k] = i
|
||||
} else {
|
||||
uf.union(i, factorMap[v/k])
|
||||
uf.Union(i, factorMap[v/k])
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, ok := factorMap[v]; !ok {
|
||||
factorMap[v] = i
|
||||
} else {
|
||||
uf.union(i, factorMap[v])
|
||||
uf.Union(i, factorMap[v])
|
||||
}
|
||||
}
|
||||
return uf.maxUnionCount
|
||||
return uf.MaxUnionCount()
|
||||
}
|
||||
|
@ -1,34 +1,38 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func regionsBySlashes(grid []string) int {
|
||||
size := len(grid)
|
||||
uf := UnionFind{}
|
||||
uf.init(4 * size * size)
|
||||
uf := template.UnionFind{}
|
||||
uf.Init(4 * size * size)
|
||||
for i := 0; i < size; i++ {
|
||||
for j := 0; j < size; j++ {
|
||||
switch grid[i][j] {
|
||||
case '\\':
|
||||
uf.union(getFaceIdx(size, i, j, 0), getFaceIdx(size, i, j, 1))
|
||||
uf.union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 3))
|
||||
uf.Union(getFaceIdx(size, i, j, 0), getFaceIdx(size, i, j, 1))
|
||||
uf.Union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 3))
|
||||
case '/':
|
||||
uf.union(getFaceIdx(size, i, j, 0), getFaceIdx(size, i, j, 3))
|
||||
uf.union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 1))
|
||||
uf.Union(getFaceIdx(size, i, j, 0), getFaceIdx(size, i, j, 3))
|
||||
uf.Union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 1))
|
||||
case ' ':
|
||||
uf.union(getFaceIdx(size, i, j, 0), getFaceIdx(size, i, j, 1))
|
||||
uf.union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 1))
|
||||
uf.union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 3))
|
||||
uf.Union(getFaceIdx(size, i, j, 0), getFaceIdx(size, i, j, 1))
|
||||
uf.Union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 1))
|
||||
uf.Union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i, j, 3))
|
||||
}
|
||||
if i < size-1 {
|
||||
uf.union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i+1, j, 0))
|
||||
uf.Union(getFaceIdx(size, i, j, 2), getFaceIdx(size, i+1, j, 0))
|
||||
}
|
||||
if j < size-1 {
|
||||
uf.union(getFaceIdx(size, i, j, 1), getFaceIdx(size, i, j+1, 3))
|
||||
uf.Union(getFaceIdx(size, i, j, 1), getFaceIdx(size, i, j+1, 3))
|
||||
}
|
||||
}
|
||||
}
|
||||
count := 0
|
||||
for i := 0; i < 4*size*size; i++ {
|
||||
if uf.find(i) == i {
|
||||
if uf.Find(i) == i {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,23 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"github.com/halfrost/LeetCode-Go/template"
|
||||
)
|
||||
|
||||
func equationsPossible(equations []string) bool {
|
||||
if len(equations) == 0 {
|
||||
return false
|
||||
}
|
||||
uf := UnionFind{}
|
||||
uf.init(26)
|
||||
uf := template.UnionFind{}
|
||||
uf.Init(26)
|
||||
for _, equ := range equations {
|
||||
if equ[1] == '=' && equ[2] == '=' {
|
||||
uf.union(int(equ[0]-'a'), int(equ[3]-'a'))
|
||||
uf.Union(int(equ[0]-'a'), int(equ[3]-'a'))
|
||||
}
|
||||
}
|
||||
for _, equ := range equations {
|
||||
if equ[1] == '!' && equ[2] == '=' {
|
||||
if uf.find(int(equ[0]-'a')) == uf.find(int(equ[3]-'a')) {
|
||||
if uf.Find(int(equ[0]-'a')) == uf.Find(int(equ[3]-'a')) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user