-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path3532-PathExistenceQueriesInAGraphI.go
More file actions
139 lines (126 loc) · 5.8 KB
/
3532-PathExistenceQueriesInAGraphI.go
File metadata and controls
139 lines (126 loc) · 5.8 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
136
137
138
139
package main
// 3532. Path Existence Queries in a Graph I
// You are given an integer n representing the number of nodes in a graph, labeled from 0 to n - 1.
// You are also given an integer array nums of length n sorted in non-decreasing order, and an integer maxDiff.
// An undirected edge exists between nodes i and j if the absolute difference between nums[i] and nums[j] is at most maxDiff (i.e., |nums[i] - nums[j]| <= maxDiff).
// You are also given a 2D integer array queries.
// For each queries[i] = [ui, vi], determine whether there exists a path between nodes ui and vi.
// Return a boolean array answer, where answer[i] is true if there exists a path between ui and vi in the ith query and false otherwise.
// Example 1:
// Input: n = 2, nums = [1,3], maxDiff = 1, queries = [[0,0],[0,1]]
// Output: [true,false]
// Explanation:
// Query [0,0]: Node 0 has a trivial path to itself.
// Query [0,1]: There is no edge between Node 0 and Node 1 because |nums[0] - nums[1]| = |1 - 3| = 2, which is greater than maxDiff.
// Thus, the final answer after processing all the queries is [true, false].
// Example 2:
// Input: n = 4, nums = [2,5,6,8], maxDiff = 2, queries = [[0,1],[0,2],[1,3],[2,3]]
// Output: [false,false,true,true]
// Explanation:
// The resulting graph is:
// <img src="https://assets.leetcode.com/uploads/2025/03/25/screenshot-2025-03-26-at-122249.png" />
// Query [0,1]: There is no edge between Node 0 and Node 1 because |nums[0] - nums[1]| = |2 - 5| = 3, which is greater than maxDiff.
// Query [0,2]: There is no edge between Node 0 and Node 2 because |nums[0] - nums[2]| = |2 - 6| = 4, which is greater than maxDiff.
// Query [1,3]: There is a path between Node 1 and Node 3 through Node 2 since |nums[1] - nums[2]| = |5 - 6| = 1 and |nums[2] - nums[3]| = |6 - 8| = 2, both of which are within maxDiff.
// Query [2,3]: There is an edge between Node 2 and Node 3 because |nums[2] - nums[3]| = |6 - 8| = 2, which is equal to maxDiff.
// Thus, the final answer after processing all the queries is [false, false, true, true].
// Constraints:
// 1 <= n == nums.length <= 10^5
// 0 <= nums[i] <= 10^5
// nums is sorted in non-decreasing order.
// 0 <= maxDiff <= 10^5
// 1 <= queries.length <= 10^5
// queries[i] == [ui, vi]
// 0 <= ui, vi < n
import "fmt"
func pathExistenceQueries(n int, nums []int, maxDiff int, queries [][]int) []bool {
var find func(u int, pa []int) int
find = func(u int, pa []int) int {
if pa[u] == u { return u }
return find(pa[u], pa)
}
merge := func(u int, v int, pa []int) {
u, v = find(u, pa), find(v, pa)
if u > v {
u, v = v, u
}
pa[v] = u
}
binarySearch := func(arr []int, target int) int {
left, right := 0, len(arr) - 1
for left <= right {
mid := left + (right - left) / 2
if arr[mid] <= target {
left = mid + 1
} else {
right = mid - 1
}
}
return right
}
pa := make([]int, n)
for i := 0; i < n; i++ {
pa[i] = i
}
for i := 0; i < n; i++ {
index := binarySearch(nums, nums[i] + maxDiff)
for j := i + 1; j <= index; j++ {
merge(j, j - 1, pa)
}
if index > i {
i = index - 1
} else {
i = index
}
}
m := len(queries)
res := make([]bool, m)
for i := 0; i < m; i++ {
u, v := queries[i][0], queries[i][1]
if find(u, pa) == find(v, pa) {
res[i] = true
} else {
res[i] = false
}
}
return res
}
func pathExistenceQueries1(n int, nums []int, maxDiff int, queries [][]int) []bool {
colors := make([]int, n)
for i, color := 1, 0; i < n; i++ {
if nums[i] - nums[i - 1] > maxDiff {
color++
}
colors[i] = color
}
m := len(queries)
res := make([]bool, m)
for i, q := range queries {
res[i] = (colors[q[0]] == colors[q[1]])
}
return res
}
func main() {
// Example 1:
// Input: n = 2, nums = [1,3], maxDiff = 1, queries = [[0,0],[0,1]]
// Output: [true,false]
// Explanation:
// Query [0,0]: Node 0 has a trivial path to itself.
// Query [0,1]: There is no edge between Node 0 and Node 1 because |nums[0] - nums[1]| = |1 - 3| = 2, which is greater than maxDiff.
// Thus, the final answer after processing all the queries is [true, false].
fmt.Println(pathExistenceQueries(2, []int{1,3}, 1, [][]int{{0,0},{0,1}})) // [true,false]
// Example 2:
// Input: n = 4, nums = [2,5,6,8], maxDiff = 2, queries = [[0,1],[0,2],[1,3],[2,3]]
// Output: [false,false,true,true]
// Explanation:
// The resulting graph is:
// <img src="https://assets.leetcode.com/uploads/2025/03/25/screenshot-2025-03-26-at-122249.png" />
// Query [0,1]: There is no edge between Node 0 and Node 1 because |nums[0] - nums[1]| = |2 - 5| = 3, which is greater than maxDiff.
// Query [0,2]: There is no edge between Node 0 and Node 2 because |nums[0] - nums[2]| = |2 - 6| = 4, which is greater than maxDiff.
// Query [1,3]: There is a path between Node 1 and Node 3 through Node 2 since |nums[1] - nums[2]| = |5 - 6| = 1 and |nums[2] - nums[3]| = |6 - 8| = 2, both of which are within maxDiff.
// Query [2,3]: There is an edge between Node 2 and Node 3 because |nums[2] - nums[3]| = |6 - 8| = 2, which is equal to maxDiff.
// Thus, the final answer after processing all the queries is [false, false, true, true].
fmt.Println(pathExistenceQueries(4, []int{2,5,6,8}, 2, [][]int{{0,1},{0,2},{1,3},{2,3}})) // [false,false,true,true]
fmt.Println(pathExistenceQueries1(2, []int{1,3}, 1, [][]int{{0,0},{0,1}})) // [true,false]
fmt.Println(pathExistenceQueries1(4, []int{2,5,6,8}, 2, [][]int{{0,1},{0,2},{1,3},{2,3}})) // [false,false,true,true]
}