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 mostmaxDiff (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.
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]`.
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:
* 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]`.
Since nums is sorted, nodes with consecutive indices are connected if their values differ by at most maxDiff. Thus, the graph consists of connected components formed by joining consecutive nodes where the difference is within maxDiff. We can use Union-Find to efficiently group nodes into components, then answer each query by checking if ui and vi are in the same component.
import java.util.*;
classSolution {
public List<Boolean>pathExistence(int n, int[] nums, int maxDiff, int[][] queries) {
int[] parent =newint[n];
for (int i = 0; i < n; ++i) parent[i]= i;
for (int i = 1; i < n; ++i) {
if (nums[i]- nums[i-1]<= maxDiff) union(parent, i, i-1);
}
List<Boolean> res =new ArrayList<>();
for (int[] q : queries) res.add(find(parent, q[0]) == find(parent, q[1]));
return res;
}
privateintfind(int[] p, int x) { return p[x]== x ? x : (p[x]= find(p, p[x])); }
privatevoidunion(int[] p, int x, int y) { p[find(p, x)]= find(p, y); }
}
1
2
3
4
5
6
7
8
9
10
11
12
funpathExistence(n: Int, nums: IntArray, maxDiff: Int, queries: Array<IntArray>): List<Boolean> {
val parent = IntArray(n) { it }
funfind(x: Int): Int {
if (parent[x] != x) parent[x] = find(parent[x])
return parent[x]
}
fununite(x: Int, y: Int) { parent[find(x)] = find(y) }
for (i in1 until n) {
if (nums[i] - nums[i-1] <= maxDiff) unite(i, i-1)
}
return queries.map { find(it[0]) == find(it[1]) }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
from typing import List
defpathExistence(n: int, nums: List[int], maxDiff: int, queries: List[List[int]]) -> List[bool]:
parent = list(range(n))
deffind(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
defunite(x, y):
parent[find(x)] = find(y)
for i in range(1, n):
if nums[i] - nums[i-1] <= maxDiff:
unite(i, i-1)
return [find(u) == find(v) for u, v in queries]
⏰ Time complexity: O(n + Q * α(n)) where α is the inverse Ackermann function (almost constant), n is the number of nodes, and Q is the number of queries.