一、Problem
在一排多米诺骨牌中,A[i] 和 B[i] 分别代表第 i 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字。)
我们可以旋转第 i 张多米诺,使得 A[i] 和 B[i] 的值交换。
返回能使 A 中所有值或者 B 中所有值都相同的最小旋转次数。
如果无法做到,返回 -1.
输入:A = [2,1,2,4,2,2], B = [5,2,6,2,3,2]
输出:2
解释:
图一表示:在我们旋转之前, A 和 B 给出的多米诺牌。
如果我们旋转第二个和第四个多米诺骨牌,我们可以使上面一行中的每个值都等于 2,如图二所示。
提示:
1 <= A[i], B[i] <= 6
2 <= A.length == B.length <= 20000
二、Solution
方法一:选基准值
思路
目标是交换 A、B 中相同位置的值实现 A/B 中的元素全等…
既然是要让数组全等,那么让数组全等的充要条件是数组中只有一种元素,基于这一点,我们可以选定任意个基准值 v,然后检查其它是否能够通过交换两个数组中的的值实现相等,这样一来每次比较的时候就会这几种情况:
- A[i] != v && B[i] != v,这种应该返回 -1,因为 A 和 B 都无法变为全等
- A[i] = v && B[i] != v,旋转即可
- B[i] = v && A[i] != v,旋转即可
class Solution {
int doRotate(int v, int[] A, int[] B, int n) {
int rotateA = 0, rotateB = 0;
for (int i = 0; i < n; i++) {
if (A[i] != v && B[i] != v) return -1;
else if (A[i] != v && B[i] == v) rotateA++; //这里不写 B[i] == v 都行
else if (B[i] != v && A[i] == v) rotateB++;
}
return Math.min(rotateA, rotateB);
}
public int minDominoRotations(int[] A, int[] B) {
int ans = doRotate(A[0], A, B, A.length);
return A[0] == B[0] || ans != -1 ? ans : doRotate(B[0], A, B, A.length);
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,