Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Checking Existence of Edge Length Limited Paths

Updated
4 min read

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 edgeList and queries. Sorting edgeList allows us to incrementally add edges to the graph based on their distances. Sorting queries allows 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 edgeList to 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 the find operation of the Union-Find data structure.
  • 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

More from this blog

C

Chatmagic blog

2894 posts