Solving Leetcode Interviews in Seconds with AI: Checking Existence of Edge Length Limited Paths
Introduction
In this blog post, we will explore how to solve the LeetCode problem "1697" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
An undirected graph of n nodes is defined by edgeList, where edgeList[i] = [ui, vi, disi] denotes an edge between nodes ui and vi with distance disi. Note that there may be multiple edges between two nodes. Given an array queries, where queries[j] = [pj, qj, limitj], your task is to determine for each queries[j] whether there is a path between pj and qj such that each edge on the path has a distance strictly less than limitj . Return a boolean array answer, where answer.length == queries.length and the jth value of answer is true if there is a path for queries[j] is true, and false otherwise. Example 1: Input: n = 3, edgeList = [[0,1,2],[1,2,4],[2,0,8],[1,0,16]], queries = [[0,1,2],[0,2,5]] Output: [false,true] Explanation: The above figure shows the given graph. Note that there are two overlapping edges between 0 and 1 with distances 2 and 16. For the first query, between 0 and 1 there is no path where each distance is less than 2, thus we return false for this query. For the second query, there is a path (0 -> 1 -> 2) of two edges with distances less than 5, thus we return true for this query. Example 2: Input: n = 5, edgeList = [[0,1,10],[1,2,5],[2,3,9],[3,4,13]], queries = [[0,4,14],[1,4,13]] Output: [true,false] Explanation: The above figure shows the given graph. Constraints: 2 <= n <= 105 1 <= edgeList.length, queries.length <= 105 edgeList[i].length == 3 queries[j].length == 3 0 <= ui, vi, pj, qj <= n - 1 ui != vi pj != qj 1 <= disi, limitj <= 109 There may be multiple edges between two nodes.
Explanation
Here's the breakdown of the approach, complexity, and the Python code:
High-Level Approach:
- Sort the
edgeListandqueries. SortingedgeListallows us to incrementally add edges to the graph based on their distances. Sortingqueriesallows us to process queries in increasing order of their limit, enabling efficient graph construction. - Use the Union-Find (Disjoint Set Union) data structure to keep track of connected components. Initially, each node is in its own component.
- Iterate through the sorted queries. For each query, add edges from the sorted
edgeListto the Union-Find data structure as long as their distance is less than the query's limit. After adding the necessary edges, check if the two nodes in the query are in the same connected component using thefindoperation of the Union-Find data structure.
- Sort the
Complexity:
- Runtime Complexity: O(E log E + Q log Q + (E + Q) α(N)), where E is the number of edges, Q is the number of queries, N is the number of nodes, and α is the inverse Ackermann function (which grows extremely slowly, practically constant). The E log E and Q log Q terms come from sorting. The (E + Q) α(N) term comes from the Union-Find operations (union and find).
- Storage Complexity: O(N + E + Q), to store the parent array for Union-Find, the sorted edge list, and the sorted queries with their original indices.
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x]) # Path compression
return self.parent[x]
def union(self, x, y):
root_x = self.find(x)
root_y = self.find(y)
if root_x != root_y:
if self.rank[root_x] < self.rank[root_y]:
self.parent[root_x] = root_y
elif self.rank[root_x] > self.rank[root_y]:
self.parent[root_y] = root_x
else:
self.parent[root_y] = root_x
self.rank[root_x] += 1
def distanceLimitedPathsExist(n: int, edgeList: list[list[int]], queries: list[list[int]]) -> list[bool]:
"""
Determines for each query whether there is a path between two nodes such that each edge on the path has a distance strictly less than the limit.
"""
edgeList.sort(key=lambda x: x[2]) # Sort edges by distance
# Add original index to queries for later result ordering
queries_with_index = [(q[0], q[1], q[2], i) for i, q in enumerate(queries)]
queries_with_index.sort(key=lambda x: x[2]) # Sort queries by limit
uf = UnionFind(n)
answer = [False] * len(queries)
edge_index = 0
for p, q, limit, query_index in queries_with_index:
# Add edges with distance < limit to the Union-Find
while edge_index < len(edgeList) and edgeList[edge_index][2] < limit:
u, v, dist = edgeList[edge_index]
uf.union(u, v)
edge_index += 1
# Check if p and q are in the same connected component
if uf.find(p) == uf.find(q):
answer[query_index] = True
return answer
</code>
# Code
```python
None