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 * 104
bottoms.length == tops.length
1 <= tops[i], bottoms[i] <= 6
有上下两行骰子的点数,交换点数使上或下行的点数都一样,返回最少的交换次数,无法得到一行一样时返回-1。
上下行点数可以是一样的。
思路:
满足交换后整行点数一样的前提是,该点数出现在上下任一行的次数==tops的长度。
其中,上下两行都出现该点数时算一次。
因为点数只有1~6,可用一个数组保存每个点数出现过的次数(上下行都出现算一次)。
然后遍历这些次数,次数==tops的长度时认为可以达到条件。
最后要计算最小交换次数,
当上下两行出现一样的点数时不需要交换,那只需要看上下两行不一样的点数就行了,
比如
去掉最后一列点数一样的,点数2在上一行出现了3次,在下一行出现了2次。
显而易见最小交换次数是2次,也就是min(3, 2)。
用一个数组top存入每个点数在上一行出现的次数(上下行一样的不计入),
数组down存入每个点数在下一行出现的次数(上下行一样的不计入),它们中较小的就是需要交换的次数。
public int minDominoRotations(int[] tops, int[] bottoms) {
int[] cnt = new int[7];
int[] top = new int[7];
int[] down = new int[7];
int result = 20000;
int n = tops.length;
for(int i = 0; i < n; i ++) {
int id1 = tops[i];
int id2 = bottoms[i];
cnt[id1] ++;
if(id1 != id2) {
cnt[id2] ++;
top[id1] ++;
down[id2] ++;
}
}
for(int i = 1; i <= 6; i ++) {
if(cnt[i] == n) {
int min = Math.min(top[i], down[i]);
result = Math.min(result, min);
}
}
return result == 20000 ? -1 : result;
}