In a row of dominoes, tops[i] and bottoms[i] represent the top and bottom halves of the ith domino. (A domino is a tile with two numbers from 1 to 6 - one on each half of the tile.)
We may rotate the ith domino, so that tops[i] and bottoms[i] swap values.
Return the minimum number of rotations so that all the values in tops are the same, or all the values in bottoms are the same.
If it cannot be done, return -1.
Example 1:
Input: tops = [2,1,2,4,2,2], bottoms = [5,2,6,2,3,2] Output: 2 Explanation: The first figure represents the dominoes as given by tops and bottoms: before we do any rotations. If we rotate the second and fourth dominoes, we can make every value in the top row equal to 2, as indicated by the second figure.
Example 2:
Input: tops = [3,5,1,2,3], bottoms = [3,6,3,3,4] Output: -1 Explanation: In this case, it is not possible to rotate the dominoes to make one row of values equal.
Constraints:
2 <= tops.length <= 2 * 104bottoms.length == tops.length1 <= tops[i], bottoms[i] <= 6When 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 solve this domino problem is to check every possible value from 1 to 6 and see if we can make either the top or bottom row have all the same value. We'll count how many flips it takes for each possibility and pick the smallest one.
Here's how the algorithm would work step-by-step:
def minimum_domino_rotations(tops, bottoms): number_of_dominoes = len(tops)
minimum_rotations = float('inf')
for target_number in range(1, 7):
# Attempt to make the top row all the target number
rotations_to_top = 0
possible = True
for index in range(number_of_dominoes):
if tops[index] != target_number:
if bottoms[index] == target_number:
rotations_to_top += 1
else:
possible = False
break
# Update minimum rotations if a solution was found
if possible:
minimum_rotations = min(minimum_rotations, rotations_to_top)
# Attempt to make the bottom row all the target number
rotations_to_bottom = 0
possible = True
for index in range(number_of_dominoes):
if bottoms[index] != target_number:
if tops[index] == target_number:
rotations_to_bottom += 1
else:
possible = False
break
# Update minimum rotations if a solution was found
if possible:
minimum_rotations = min(minimum_rotations, rotations_to_bottom)
# If no solution was found, return -1
if minimum_rotations == float('inf'):
return -1
else:
return minimum_rotationsThe fastest way to solve this is to realize we only care if one of the numbers from the first domino can potentially make an entire row the same. We count how many rotations it takes to make either of those numbers fill a row, and the smaller rotation count is the answer.
Here's how the algorithm would work step-by-step:
def minDominoRotations(tops, bottoms):
first_domino_top_value = tops[0]
first_domino_bottom_value = bottoms[0]
number_of_dominoes = len(tops)
def calculate_rotations(target_value, target_row):
rotations_needed = 0
for i in range(number_of_dominoes):
if target_row == 'tops':
if tops[i] != target_value:
if bottoms[i] == target_value:
rotations_needed += 1
else:
return float('inf')
else:
if bottoms[i] != target_value:
if tops[i] == target_value:
rotations_needed += 1
else:
return float('inf')
return rotations_needed
#Calculate rotations needed for the top row to match first domino top value
top_rotations_for_first_top = calculate_rotations(first_domino_top_value, 'tops')
#Calculate rotations needed for the bottom row to match first domino top value
bottom_rotations_for_first_top = calculate_rotations(first_domino_top_value, 'bottoms')
#Calculate rotations needed for the top row to match first domino bottom value
top_rotations_for_first_bottom = calculate_rotations(first_domino_bottom_value, 'tops')
#Calculate rotations needed for the bottom row to match first domino bottom value
bottom_rotations_for_first_bottom = calculate_rotations(first_domino_bottom_value, 'bottoms')
minimum_rotations = min(top_rotations_for_first_top,
bottom_rotations_for_first_top,
top_rotations_for_first_bottom,
bottom_rotations_for_first_bottom)
# If it's impossible return -1
if minimum_rotations == float('inf'):
return -1
return minimum_rotations| Case | How to Handle |
|---|---|
| Empty input arrays A or B | Return -1 immediately since no rotations are possible. |
| Arrays A and B have different lengths | Return -1 since a common row cannot be achieved. |
| Arrays A and B have a single element | Return 0 if the single elements are equal, and -1 otherwise. |
| All elements in both A and B are the same | Return 0 since no rotations are needed. |
| No number appears in all of A or all of B | Return -1, indicating no solution is possible. |
| Arrays A and B are identical, but no number is the same throughout | This should correctly result in -1 being returned. |
| Arrays A and B have very large size (performance consideration) | Ensure the algorithm iterates the array only a constant number of times (O(n) time complexity). |
| Integer overflow if counting rotations with very large array sizes | The number of rotations will never exceed the array size; thus, integer overflow is not a concern. |