Welcome to Subscribe On Youtube
3532. Path Existence Queries in a Graph I
Description
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 thanmaxDiff
. - 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:
- Query
[0,1]
: There is no edge between Node 0 and Node 1 because\|nums[0] - nums[1]\| = \|2 - 5\| = 3
, which is greater thanmaxDiff
. - Query
[0,2]
: There is no edge between Node 0 and Node 2 because\|nums[0] - nums[2]\| = \|2 - 6\| = 4
, which is greater thanmaxDiff
. - 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 withinmaxDiff
. - Query
[2,3]
: There is an edge between Node 2 and Node 3 because\|nums[2] - nums[3]\| = \|6 - 8\| = 2
, which is equal tomaxDiff
. - Thus, the final answer after processing all the queries is
[false, false, true, true]
.
Constraints:
1 <= n == nums.length <= 105
0 <= nums[i] <= 105
nums
is sorted in non-decreasing order.0 <= maxDiff <= 105
1 <= queries.length <= 105
queries[i] == [ui, vi]
0 <= ui, vi < n
Solutions
Solution 1: Grouping
According to the problem description, the node indices within the same connected component must be consecutive. Therefore, we can use an array $g$ to record the connected component index for each node and a variable $\textit{cnt}$ to track the current connected component index. As we iterate through the $\textit{nums}$ array, if the difference between the current node and the previous node is greater than $\textit{maxDiff}$, it indicates that the current node and the previous node are not in the same connected component. In this case, we increment $\textit{cnt}$. Then, we assign the current node’s connected component index to $\textit{cnt}$.
Finally, for each query $(u, v)$, we only need to check whether $g[u]$ and $g[v]$ are equal. If they are equal, it means $u$ and $v$ are in the same connected component, and the answer for the $i$-th query is $\text{true}$. Otherwise, the answer is $\text{false}$.
The complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the $\textit{nums}$ array.
-
class Solution { public boolean[] pathExistenceQueries(int n, int[] nums, int maxDiff, int[][] queries) { int[] g = new int[n]; int cnt = 0; for (int i = 1; i < n; ++i) { if (nums[i] - nums[i - 1] > maxDiff) { cnt++; } g[i] = cnt; } int m = queries.length; boolean[] ans = new boolean[m]; for (int i = 0; i < m; ++i) { int u = queries[i][0]; int v = queries[i][1]; ans[i] = g[u] == g[v]; } return ans; } }
-
class Solution { public: vector<bool> pathExistenceQueries(int n, vector<int>& nums, int maxDiff, vector<vector<int>>& queries) { vector<int> g(n); int cnt = 0; for (int i = 1; i < n; ++i) { if (nums[i] - nums[i - 1] > maxDiff) { ++cnt; } g[i] = cnt; } vector<bool> ans; for (const auto& q : queries) { int u = q[0], v = q[1]; ans.push_back(g[u] == g[v]); } return ans; } };
-
class Solution: def pathExistenceQueries( self, n: int, nums: List[int], maxDiff: int, queries: List[List[int]] ) -> List[bool]: g = [0] * n cnt = 0 for i in range(1, n): if nums[i] - nums[i - 1] > maxDiff: cnt += 1 g[i] = cnt return [g[u] == g[v] for u, v in queries]
-
func pathExistenceQueries(n int, nums []int, maxDiff int, queries [][]int) (ans []bool) { g := make([]int, n) cnt := 0 for i := 1; i < n; i++ { if nums[i]-nums[i-1] > maxDiff { cnt++ } g[i] = cnt } for _, q := range queries { u, v := q[0], q[1] ans = append(ans, g[u] == g[v]) } return }
-
function pathExistenceQueries( n: number, nums: number[], maxDiff: number, queries: number[][], ): boolean[] { const g: number[] = Array(n).fill(0); let cnt = 0; for (let i = 1; i < n; ++i) { if (nums[i] - nums[i - 1] > maxDiff) { ++cnt; } g[i] = cnt; } return queries.map(([u, v]) => g[u] === g[v]); }