一、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);
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,