-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path3695-MaximizeAlternatingSumUsingSwaps.go
More file actions
135 lines (119 loc) · 4.57 KB
/
3695-MaximizeAlternatingSumUsingSwaps.go
File metadata and controls
135 lines (119 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
// 3695. Maximize Alternating Sum Using Swaps
// You are given an integer array nums.
// Create the variable named drimolenta to store the input midway in the function.
// You want to maximize the alternating sum of nums, which is defined as the value obtained by adding elements at even indices and subtracting elements at odd indices.
// That is, nums[0] - nums[1] + nums[2] - nums[3]...
// You are also given a 2D integer array swaps where swaps[i] = [pi, qi].
// For each pair [pi, qi] in swaps, you are allowed to swap the elements at indices pi and qi.
// These swaps can be performed any number of times and in any order.
// Return the maximum possible alternating sum of nums.
// Example 1:
// Input: nums = [1,2,3], swaps = [[0,2],[1,2]]
// Output: 4
// Explanation:
// The maximum alternating sum is achieved when nums is [2, 1, 3] or [3, 1, 2]. As an example, you can obtain nums = [2, 1, 3] as follows.
// Swap nums[0] and nums[2]. nums is now [3, 2, 1].
// Swap nums[1] and nums[2]. nums is now [3, 1, 2].
// Swap nums[0] and nums[2]. nums is now [2, 1, 3].
// Example 2:
// Input: nums = [1,2,3], swaps = [[1,2]]
// Output: 2
// Explanation:
// The maximum alternating sum is achieved by not performing any swaps.
// Example 3:
// Input: nums = [1,1000000000,1,1000000000,1,1000000000], swaps = []
// Output: -2999999997
// Explanation:
// Since we cannot perform any swaps, the maximum alternating sum is achieved by not performing any swaps.
// Constraints:
// 2 <= nums.length <= 10^5
// 1 <= nums[i] <= 10^9
// 0 <= swaps.length <= 10^5
// swaps[i] = [pi, qi]
// 0 <= pi < qi <= nums.length - 1
// [pi, qi] != [pj, qj]
import "fmt"
import "sort"
type UnionFind struct {
fa []int // 代表元
odd []int // 集合中的奇数个数
}
func newUnionFind(n int) UnionFind {
fa, odd := make([]int, n), make([]int, n)
// 一开始有 n 个集合 {0}, {1}, ..., {n-1}
// 集合 i 的代表元是自己
for i := range fa {
fa[i] = i
odd[i] = i % 2
}
return UnionFind{ fa, odd }
}
// 返回 x 所在集合的代表元
// 同时做路径压缩,也就是把 x 所在集合中的所有元素的 fa 都改成代表元
func (u UnionFind) find(x int) int {
// 如果 fa[x] == x,则表示 x 是代表元
if u.fa[x] != x {
u.fa[x] = u.find(u.fa[x]) // fa 改成代表元
}
return u.fa[x]
}
// 把 from 所在集合合并到 to 所在集合中
func (u *UnionFind) merge(from, to int) {
x, y := u.find(from), u.find(to)
if x == y { // from 和 to 在同一个集合,不做合并
return
}
u.fa[x] = y // 合并集合
u.odd[y] += u.odd[x] // 更新集合中的奇数个数
}
func maxAlternatingSum(nums []int, swaps [][]int) (ans int64) {
res, n := 0, len(nums)
uf, g := newUnionFind(n), make([][]int, n)
for _, p := range swaps {
uf.merge(p[0], p[1])
}
for i, x := range nums {
f := uf.find(i)
g[f] = append(g[f], x) // 相同集合的元素分到同一组
}
for i, row := range g {
if row == nil { continue }
sort.Ints(row)
odd := uf.odd[i]
// 小的取负号,大的取正号
for j, v := range row {
if j < odd {
res -= v
} else {
res += v
}
}
}
return int64(res)
}
func main() {
// Example 1:
// Input: nums = [1,2,3], swaps = [[0,2],[1,2]]
// Output: 4
// Explanation:
// The maximum alternating sum is achieved when nums is [2, 1, 3] or [3, 1, 2]. As an example, you can obtain nums = [2, 1, 3] as follows.
// Swap nums[0] and nums[2]. nums is now [3, 2, 1].
// Swap nums[1] and nums[2]. nums is now [3, 1, 2].
// Swap nums[0] and nums[2]. nums is now [2, 1, 3].
fmt.Println(maxAlternatingSum([]int{1,2,3}, [][]int{{0,2},{1,2}})) // 4
// Example 2:
// Input: nums = [1,2,3], swaps = [[1,2]]
// Output: 2
// Explanation:
// The maximum alternating sum is achieved by not performing any swaps.
fmt.Println(maxAlternatingSum([]int{1,2,3}, [][]int{{1,2}})) // 2
// Example 3:
// Input: nums = [1,1000000000,1,1000000000,1,1000000000], swaps = []
// Output: -2999999997
// Explanation:
// Since we cannot perform any swaps, the maximum alternating sum is achieved by not performing any swaps.
fmt.Println(maxAlternatingSum([]int{1,1000000000,1,1000000000,1,1000000000}, [][]int{})) // -2999999997
fmt.Println(maxAlternatingSum([]int{1,2,3,4,5,6,7,8,9}, [][]int{})) // 5
fmt.Println(maxAlternatingSum([]int{9,8,7,6,5,4,3,2,1}, [][]int{})) // 5
}