There is an integer array nums
that consists of n
unique elements, but you have forgotten it. However, you do remember every pair of adjacent elements in nums
.
You are given a 2D integer array adjacentPairs
of size n - 1
where each adjacentPairs[i] = [ui, vi]
indicates that the elements ui
and vi
are adjacent in nums
.
It is guaranteed that every adjacent pair of elements nums[i]
and nums[i+1]
will exist in adjacentPairs
, either as [nums[i], nums[i+1]]
or [nums[i+1], nums[i]]
. The pairs can appear in any order.
Return the original array nums
. If there are multiple solutions, return any of them.
Example 1:
Input: adjacentPairs = [[2,1],[3,4],[3,2]] Output: [1,2,3,4] Explanation: This array has all its adjacent pairs in adjacentPairs. Notice that adjacentPairs[i] may not be in left-to-right order.
Example 2:
Input: adjacentPairs = [[4,-2],[1,4],[-3,1]] Output: [-2,4,1,-3] Explanation: There can be negative numbers. Another solution is [-3,1,4,-2], which would also be accepted.
Example 3:
Input: adjacentPairs = [[100000,-100000]] Output: [100000,-100000]
Constraints:
nums.length == n
adjacentPairs.length == n - 1
adjacentPairs[i].length == 2
2 <= n <= 105
-105 <= nums[i], ui, vi <= 105
nums
that has adjacentPairs
as its pairs.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 brute force approach to reconstructing the array involves trying every possible starting number and checking if we can build a valid array. We'll keep track of visited numbers to avoid cycles and exhaustively explore all potential paths. It's like trying to solve a maze by trying every possible turn at each intersection.
Here's how the algorithm would work step-by-step:
def restore_array_brute_force(adjacent_pairs):
numbers = set()
for pair in adjacent_pairs:
numbers.add(pair[0])
numbers.add(pair[1])
for start_number in numbers:
array = [start_number]
visited = {start_number}
current_number = start_number
temp_pairs = adjacent_pairs[:]
while len(array) < len(numbers):
next_number = None
pair_to_remove = None
for pair_index, pair in enumerate(temp_pairs):
if current_number in pair:
possible_next_number = pair[0] if pair[1] == current_number else pair[1]
# Prevents cycles by checking if the next number has already been visited
if possible_next_number not in visited:
next_number = possible_next_number
pair_to_remove = pair_index
break
if next_number is None:
break
array.append(next_number)
visited.add(next_number)
current_number = next_number
del temp_pairs[pair_to_remove]
# Check if a valid array was found.
if len(array) == len(numbers):
return array
return []
The problem gives you pairs of numbers that were next to each other in an original sequence, but the sequence is scrambled. The optimal strategy is to reconstruct the sequence by finding the endpoints and tracing the connections between pairs.
Here's how the algorithm would work step-by-step:
def restore_the_array_from_adjacent_pairs(adjacentPairs):
graph = {}
for pair in adjacentPairs:
number1, number2 = pair
if number1 not in graph:
graph[number1] = []
if number2 not in graph:
graph[number2] = []
graph[number1].append(number2)
graph[number2].append(number1)
# Find the start node, which has only one neighbor.
start_node = None
for node, neighbors in graph.items():
if len(neighbors) == 1:
start_node = node
break
result = []
visited = set()
current_node = start_node
# Build the array by traversing the graph.
while current_node is not None:
result.append(current_node)
visited.add(current_node)
next_node = None
# Find the next unvisited neighbor.
if current_node in graph:
for neighbor in graph[current_node]:
if neighbor not in visited:
next_node = neighbor
break
current_node = next_node
return result
Case | How to Handle |
---|---|
Null or empty input array | Return an empty array to signify no solution can be generated. |
Input array with only one pair | Handle correctly by identifying the start and end based on the single pair provided. |
Maximum number of pairs within allowed memory constraints | Ensure the used data structures (e.g., hash map) can scale efficiently to handle the maximum input size without memory issues. |
Input represents a cyclic graph (no clear start or end) | Detect cycles and return an empty array as no valid linear restoration is possible. |
Input contains pairs that form disconnected components | Return an empty array because the components cannot be connected into a single sequence |
Input contains duplicate pairs | The algorithm should ignore duplicate pairs or handle them by overwriting in the adjacency list. |
The graph structure does not result in a unique path | If multiple valid solutions exist, the algorithm can return any one of them, or indicate non-uniqueness. |
Integer overflow when performing calculations on large numbers in the input | Use appropriate data types (e.g., long) to prevent overflow during computations. |