You are given a 0-indexed integer array nums representing the initial positions of some marbles. You are also given two 0-indexed integer arrays moveFrom and moveTo of equal length.
Throughout moveFrom.length steps, you will change the positions of the marbles. On the ith step, you will move all marbles at position moveFrom[i] to position moveTo[i].
After completing all the steps, return the sorted list of occupied positions.
Notes:
Example 1:
Input: nums = [1,6,7,8], moveFrom = [1,7,2], moveTo = [2,9,5] Output: [5,6,8,9] Explanation: Initially, the marbles are at positions 1,6,7,8. At the i = 0th step, we move the marbles at position 1 to position 2. Then, positions 2,6,7,8 are occupied. At the i = 1st step, we move the marbles at position 7 to position 9. Then, positions 2,6,8,9 are occupied. At the i = 2nd step, we move the marbles at position 2 to position 5. Then, positions 5,6,8,9 are occupied. At the end, the final positions containing at least one marbles are [5,6,8,9].
Example 2:
Input: nums = [1,1,3,3], moveFrom = [1,3], moveTo = [2,2] Output: [2] Explanation: Initially, the marbles are at positions [1,1,3,3]. At the i = 0th step, we move all the marbles at position 1 to position 2. Then, the marbles are at positions [2,2,3,3]. At the i = 1st step, we move all the marbles at position 3 to position 2. Then, the marbles are at positions [2,2,2,2]. Since 2 is the only occupied position, we return [2].
Constraints:
1 <= nums.length <= 1051 <= moveFrom.length <= 105moveFrom.length == moveTo.length1 <= nums[i], moveFrom[i], moveTo[i] <= 109moveFrom[i] at the moment we want to apply the ith move.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 way to relocate marbles is like physically trying out every possible move. We consider each possible swap of marbles between boxes until we find a configuration that meets the desired condition. It’s thorough but not efficient.
Here's how the algorithm would work step-by-step:
def relocate_marbles_brute_force(initial_state, target_state, max_moves=5):
def states_equal(state1, state2):
return state1 == state2
def get_possible_next_states(current_state):
possible_states = []
number_of_boxes = len(current_state)
for from_box_index in range(number_of_boxes):
for to_box_index in range(number_of_boxes):
if from_box_index != to_box_index:
new_state = current_state[:]
new_state[from_box_index], new_state[to_box_index] = \
new_state[to_box_index], new_state[from_box_index]
possible_states.append(new_state)
return possible_states
def search(current_state, moves_remaining):
if states_equal(current_state, target_state):
return True
if moves_remaining == 0:
return False
# Iterate through all possible next states and recursively search
for next_state in get_possible_next_states(current_state):
if search(next_state, moves_remaining - 1):
return True
return False
# Try increasing the number of moves until max_moves is reached
for moves in range(1, max_moves + 1):
if search(initial_state, moves):
return True
# No solution found within the maximum number of moves
return FalseTo efficiently move marbles, we use a counting-based approach. Instead of directly swapping marbles, we keep track of how many marbles are supposed to be in each location after all the moves are complete. This allows us to quickly determine the final configuration without actually moving anything.
Here's how the algorithm would work step-by-step:
def relocate_marbles(locations, moves):
marble_counts = {}
for location in locations:
marble_counts[location] = marble_counts.get(location, 0) + 1
# Update marble counts based on moves
for move_from, move_to in moves:
if move_from in marble_counts:
# Reduce count from original location
marble_counts[move_from] -= 1
if marble_counts[move_from] == 0:
del marble_counts[move_from]
# Increase count to new location
marble_counts[move_to] = marble_counts.get(move_to, 0) + 1
final_locations = []
# Reconstruct the final marble arrangement
for location in sorted(marble_counts.keys()):
for _ in range(marble_counts[location]):
final_locations.append(location)
return final_locations| Case | How to Handle |
|---|---|
| Null input array | Throw IllegalArgumentException or return an empty array to signal invalid input. |
| Empty 'move' list or 'moveFrom' and 'moveTo' lists of zero length | If no moves are specified, return the original marbles array unchanged. |
| 'moveFrom' and 'moveTo' lists of different lengths | Throw IllegalArgumentException because the moves cannot be applied if the lists have different sizes. |
| Invalid 'moveFrom' index (out of bounds for the marbles array) | Throw IndexOutOfBoundsException when the 'moveFrom' index is less than 0 or greater than or equal to the marbles array's length. |
| Applying moves results in an index conflict (moving two marbles to the same position) | Ensure that the 'moveTo' indices are unique to prevent overwriting marbles in the final arrangement. |
| Large input array and many moves, potentially impacting performance. | Use an efficient data structure like an array to directly update the marbles positions based on the moves. |
| The 'moveFrom' and 'moveTo' contain the same index | Ignore the moves where the `moveFrom` index is the same as the `moveTo` index as it doesn't change anything. |
| Integer overflow if indices or array lengths are very large | Use long type for indexing or lengths if the size of input arrays or number of moves are sufficiently large to potentially cause integer overflow |