You are given an undirected graph consisting of n
nodes numbered from 1
to n
. You are also given a 2D array edges
where edges[i] = [a_i, b_i]
indicates that there is an edge between nodes a_i
and b_i
. The graph can be disconnected.
You can add at most two additional edges (possibly none) to this graph so that there are no repeated edges and no self-loops.
Can you determine if it is possible to make the degree of each node in the graph even? The degree of a node is the number of edges connected to it.
Example 1:
n = 5, edges = [[1,2],[2,3],[3,4],[4,2],[1,4],[2,5]]
In this example, the output should be true
because you can add an edge between nodes 1 and 5. All nodes will then have even degrees.
Example 2:
n = 4, edges = [[1,2],[3,4]]
In this example, the output should be true
because you can add edges between nodes 1 and 3, and between nodes 2 and 4. All nodes will then have even degrees.
Example 3:
n = 4, edges = [[1,2],[1,3],[1,4]]
In this example, the output should be false
because it is not possible to obtain a valid graph with all even degrees by adding at most 2 edges.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The goal is to make sure every point in a network connects to an even number of other points. The brute force approach tries every possible combination of adding connections until we find one where all points have an even number of connections.
Here's how the algorithm would work step-by-step:
def add_edges_to_make_degrees_even(number_of_nodes, existing_edges): odd_degree_nodes = []
for node in range(1, number_of_nodes + 1):
degree = 0
for edge_start, edge_end in existing_edges:
if node == edge_start or node == edge_end:
degree += 1
if degree % 2 != 0:
odd_degree_nodes.append(node)
if not odd_degree_nodes:
return []
# If only 2 nodes have odd degree, add an edge between them
if len(odd_degree_nodes) == 2:
return [(odd_degree_nodes[0], odd_degree_nodes[1])]
# Attempt to fix by adding one edge
for i in range(len(odd_degree_nodes)):
for j in range(i + 1, len(odd_degree_nodes)):
edge_to_add = (odd_degree_nodes[i], odd_degree_nodes[j])
temp_edges = existing_edges + [edge_to_add]
all_even = True
for node in range(1, number_of_nodes + 1):
degree = 0
for edge_start, edge_end in temp_edges:
if node == edge_start or node == edge_end:
degree += 1
if degree % 2 != 0:
all_even = False
break
if all_even:
return [edge_to_add]
# Attempt to fix by adding two edges
for i in range(len(odd_degree_nodes)):
for j in range(i + 1, len(odd_degree_nodes)):
for k in range(len(odd_degree_nodes)):
for l in range(k + 1, len(odd_degree_nodes)):
# Ensure unique pairings
if len(set([i, j, k, l])) != 4:
continue
edge_one = (odd_degree_nodes[i], odd_degree_nodes[j])
edge_two = (odd_degree_nodes[k], odd_degree_nodes[l])
temp_edges = existing_edges + [edge_one, edge_two]
all_even = True
# Check if all degrees are even
for node in range(1, number_of_nodes + 1):
degree = 0
for edge_start, edge_end in temp_edges:
if node == edge_start or node == edge_end:
degree += 1
if degree % 2 != 0:
all_even = False
break
if all_even:
return [edge_one, edge_two]
return []
The goal is to make sure every point in our network has an even number of connections. We achieve this by selectively adding new connections between points that currently have an odd number of connections, ensuring we do it in the most efficient way possible.
Here's how the algorithm would work step-by-step:
def add_edges_to_make_degrees_even(number_of_nodes, edges):
odd_degree_nodes = []
adjacency_list = [[] for _ in range(number_of_nodes)]
for node1, node2 in edges:
adjacency_list[node1].append(node2)
adjacency_list[node2].append(node1)
for node_index in range(number_of_nodes):
if len(adjacency_list[node_index]) % 2 != 0:
odd_degree_nodes.append(node_index)
number_of_odd_nodes = len(odd_degree_nodes)
if number_of_odd_nodes == 0:
return []
if number_of_odd_nodes % 2 != 0:
return None
new_edges = []
# Pair up odd degree nodes and add edges.
for i in range(0, number_of_odd_nodes, 2):
node1 = odd_degree_nodes[i]
node2 = odd_degree_nodes[i+1]
# Check if the edge already exists.
if node2 not in adjacency_list[node1]:
new_edges.append((node1, node2))
else:
#If nodes are already connected, connect node1 to a new node.
for potential_connection_node in range(number_of_nodes):
if potential_connection_node != node1 and potential_connection_node not in adjacency_list[node1]:
new_edges.append((node1, potential_connection_node))
break
return new_edges
Case | How to Handle |
---|---|
Null or empty graph (no nodes) | Return an empty list, as there are no edges to add. |
Graph with only one node | Return an empty list, as a single node trivially has an even degree. |
All nodes initially have even degrees | Return an empty list because no edges need to be added. |
Only two nodes with odd degrees | Add an edge directly between these two nodes. |
Four nodes with odd degrees (the most interesting case) | Try all three possible pairings of the four nodes with odd degrees and return the first one that works. |
More than four nodes with odd degrees (impossible) | Return an empty list, since it's impossible to have an odd number of nodes with odd degrees. |
Graph is already fully connected (adding edges might create parallel edges, but degrees still become even) | The algorithm should still correctly identify and add edges between odd-degree nodes, potentially creating parallel edges which are allowed. |
Self-loops already exist in the graph | The algorithm should correctly identify nodes with odd degrees after considering the existing self-loops. |