LeetCodee

684. Redundant Connection

Jump to Solution: Python Java C++ JavaScript C#

Problem Description

In this problem, a tree is an undirected graph that is connected and has no cycles.

You are given a graph that started as a tree with n nodes labeled from 1 to n, with one additional edge added. The added edge has two different vertices chosen from 1 to n, and was not an edge that already existed. The graph is represented as an array edges of length n where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the graph.

Return an edge that can be removed so that the resulting graph is a tree of n nodes. If there are multiple answers, return the answer that occurs last in the input.

Examples:

Example 1:

Input: edges = [[1,2],[1,3],[2,3]]
Output: [2,3]

Example 2:

Input: edges = [[1,2],[2,3],[3,4],[1,4],[1,5]]
Output: [1,4]

Constraints:

  • n == edges.length
  • 3 ≤ n ≤ 1000
  • edges[i].length == 2
  • 1 ≤ ai < bi ≤ edges.length
  • ai != bi
  • There are no repeated edges
  • The given graph is connected

Python Solution

class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        parent = list(range(len(edges) + 1))
        
        def find(x):
            if parent[x] != x:
                parent[x] = find(parent[x])
            return parent[x]
        
        def union(x, y):
            parent[find(x)] = find(y)
            
        for edge in edges:
            if find(edge[0]) == find(edge[1]):
                return edge
            union(edge[0], edge[1])
            
        return []

Implementation Notes:

  • Uses Union-Find (Disjoint Set) data structure
  • Time complexity: O(N) where N is the number of edges
  • Space complexity: O(N)
  • Path compression optimization in find operation

Java Solution

class Solution {
    private int[] parent;
    
    public int[] findRedundantConnection(int[][] edges) {
        parent = new int[edges.length + 1];
        for (int i = 0; i <= edges.length; i++) {
            parent[i] = i;
        }
        
        for (int[] edge : edges) {
            if (find(edge[0]) == find(edge[1])) {
                return edge;
            }
            union(edge[0], edge[1]);
        }
        
        return new int[]{};
    }
    
    private int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    
    private void union(int x, int y) {
        parent[find(x)] = find(y);
    }
}

C++ Solution

class Solution {
private:
    vector parent;
    
    int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    
    void union_set(int x, int y) {
        parent[find(x)] = find(y);
    }
    
public:
    vector findRedundantConnection(vector>& edges) {
        parent.resize(edges.size() + 1);
        for (int i = 0; i <= edges.size(); i++) {
            parent[i] = i;
        }
        
        for (const auto& edge : edges) {
            if (find(edge[0]) == find(edge[1])) {
                return edge;
            }
            union_set(edge[0], edge[1]);
        }
        
        return {};
    }
};

JavaScript Solution

/**
 * @param {number[][]} edges
 * @return {number[]}
 */
var findRedundantConnection = function(edges) {
    const parent = Array.from({length: edges.length + 1}, (_, i) => i);
    
    const find = (x) => {
        if (parent[x] !== x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    };
    
    const union = (x, y) => {
        parent[find(x)] = find(y);
    };
    
    for (const [x, y] of edges) {
        if (find(x) === find(y)) {
            return [x, y];
        }
        union(x, y);
    }
    
    return [];
};

C# Solution

public class Solution {
    private int[] parent;
    
    public int[] FindRedundantConnection(int[][] edges) {
        parent = new int[edges.Length + 1];
        for (int i = 0; i <= edges.Length; i++) {
            parent[i] = i;
        }
        
        foreach (var edge in edges) {
            if (Find(edge[0]) == Find(edge[1])) {
                return edge;
            }
            Union(edge[0], edge[1]);
        }
        
        return new int[]{};
    }
    
    private int Find(int x) {
        if (parent[x] != x) {
            parent[x] = Find(parent[x]);
        }
        return parent[x];
    }
    
    private void Union(int x, int y) {
        parent[Find(x)] = Find(y);
    }
}

Implementation Notes:

  • Uses Union-Find data structure with path compression
  • Time complexity: O(N) where N is the number of edges
  • Space complexity: O(N)
  • Returns the last edge that creates a cycle