【数组】B082_LC_行相等的最少多米诺旋转(选基准值)

一、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);
    }
}
复杂度分析
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章