问题背景
在一排多米诺骨牌中,tops[i]tops[i]tops[i] 和 bottoms[i]bottoms[i]bottoms[i] 分别代表第 iii 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 111 到 666 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字。)
我们可以旋转第 iii 张多米诺,使得 tops[i]tops[i]tops[i] 和 bottoms[i]bottoms[i]bottoms[i] 的值交换。
返回能使 topstopstops 中所有值或者 bottomsbottomsbottoms 中所有值都相同的最小旋转次数。
如果无法做到,返回 −1-1−1。
数据约束
- 2≤tops.length≤2×1042 \le tops.length \le 2 \times 10 ^ 42≤tops.length≤2×104
- bottoms.length=tops.lengthbottoms.length = tops.lengthbottoms.length=tops.length
- 1≤tops[i],bottoms[i]≤61 \le tops[i], bottoms[i] \le 61≤tops[i],bottoms[i]≤6
解题过程
结果要求所有元素都相同,那这意味着如果最后能实现,那么取初始状态的任意一个元素,它或它的翻转状态一定被包含在结果中。
为了方便起见,分别取 top[0]top[0]top[0] 和 bottom[0]bottom[0]bottom[0] 作为目标,分别计算最小次数,再取其中较小的那个就可以了。
具体实现
class Solution {
public int minDominoRotations(int[] tops, int[] bottoms) {
int res = Math.min(minRot(tops, bottoms, tops[0]), minRot(tops, bottoms, bottoms[0]));
return res == Integer.MAX_VALUE ? -1 : res;
}
private int minRot(int[] tops, int[] bottoms, int target) {
int toTop = 0;
int toBottom = 0;
for (int i = 0; i < tops.length; i++) {
int x = tops[i];
int y = bottoms[i];
if (x != target && y != target) {
return Integer.MAX_VALUE;
}
if (x != target) {
toTop++;
} else if (y != target) {
toBottom++;
}
}
return Math.min(toTop, toBottom);
}
}