列表

详情


1007. 行相等的最少多米诺旋转

在一排多米诺骨牌中,A[i]B[i] 分别代表第 i 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字。)

我们可以旋转第 i 张多米诺,使得 A[i] 和 B[i] 的值交换。

返回能使 A 中所有值或者 B 中所有值都相同的最小旋转次数。

如果无法做到,返回 -1.

 

示例 1:

输入:A = [2,1,2,4,2,2], B = [5,2,6,2,3,2]
输出:2
解释:
图一表示:在我们旋转之前, A 和 B 给出的多米诺牌。
如果我们旋转第二个和第四个多米诺骨牌,我们可以使上面一行中的每个值都等于 2,如图二所示。

示例 2:

输入:A = [3,5,1,2,3], B = [3,6,3,3,4]
输出:-1
解释:
在这种情况下,不可能旋转多米诺牌使一行的值相等。

 

提示:

  1. 1 <= A[i], B[i] <= 6
  2. 2 <= A.length == B.length <= 20000

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int minDominoRotations(vector<int>& tops, vector<int>& bottoms) { } };

python3 解法, 执行用时: 80 ms, 内存消耗: 16.9 MB, 提交时间: 2023-09-23 00:36:48

class Solution:       
    # 官方题解,贪心
    def minDominoRotations1(self, A: List[int], B: List[int]) -> int:
        def check(x):
            """
            Return min number of swaps 
            if one could make all elements in A or B equal to x.
            Else return -1.
            """
            # how many rotations should be done
            # to have all elements in A equal to x
            # and to have all elements in B equal to x
            rotations_a = rotations_b = 0
            for i in range(n):
                # rotations coudn't be done
                if A[i] != x and B[i] != x:
                    return -1
                # A[i] != x and B[i] == x
                elif A[i] != x:
                    rotations_a += 1
                # A[i] == x and B[i] != x    
                elif B[i] != x:
                    rotations_b += 1
            # min number of rotations to have all
            # elements equal to x in A or B
            return min(rotations_a, rotations_b)
    
        n = len(A)
        rotations = check(A[0]) 
        # If one could make all elements in A or B equal to A[0]
        if rotations != -1 or A[0] == B[0]:
            return rotations 
        # If one could make all elements in A or B equal to B[0]
        else:
            return check(B[0])
            

    def minDominoRotations(self, A: List[int], B: List[int]) -> int:
        def get_min_cnt(key: int) -> int:
            up = 0      #都放在上面行
            down = 0    #都放在下面行
            for x,y in zip(A, B):
                if x != key and y != key:
                    return float('inf')
                elif x == key and y == key:
                    continue
                elif x == key and y != key:
                    down += 1
                else:
                    up += 1
            return min(up, down)

        res1 = get_min_cnt(A[0])
        res2 = get_min_cnt(B[0])
        return -1 if (res1 == res2 == float('inf')) else min(res1, res2)

golang 解法, 执行用时: 104 ms, 内存消耗: 7 MB, 提交时间: 2023-09-23 00:35:50

func minDominoRotations(A []int, B []int) int {
	nums := [7]int{}
	as := [7]int{}
	bs := [7]int{}
	for i := 0; i < len(A); i++ {
		if A[i] == B[i] {
			nums[A[i]]++
		} else {
			nums[A[i]]++
			as[A[i]]++
			nums[B[i]]++
			bs[B[i]]++
		}
	}
	for k, v := range nums {
		if v == len(A) {
			return min(as[k], bs[k])
		}
	}
	return -1
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

javascript 解法, 执行用时: 88 ms, 内存消耗: 49.7 MB, 提交时间: 2023-09-23 00:35:28

/**
 * @param {number[]} tops
 * @param {number[]} bottoms
 * @return {number}
 */
var minDominoRotations = function (tops, bottoms) {
    let len = tops.length;
    // 求 tops 或 bottoms 全部变成 tops[0],最少需要多少次旋转  Ï   
    let rotations = check(tops[0], tops, bottoms, len);
    // 如果 tops[0]==bottoms[0], 那么不用继续检查 bottoms[0]
    // 如果 tops[0]!=bottoms[0], 且可以将 tops 或 bottoms 中的元素全部变成 tops[0],那么也不用再检查 bottoms[0]
    if (rotations != -1 || tops[0] == bottoms[0]) {
        return rotations;
    } else {
        // 如果 tops[0] 不满⾜并且 tops[0]!=bottoms[0]
        // 求解 tops 或 bottoms 全部变成 bottoms[0],最少需要多少次旋转
        return check(bottoms[0], tops, bottoms, len);
    }
};

// 检查将 tops 或者 bottoms 中元素全部变成 x 需要多少次旋转
var check = function (x, tops, bottoms, len) {
    // rotationsTops 存储将 tops 中元素变成 x 需要多少次旋转
    // rotationsBottoms 存储将 bottoms 中元素变成 x 需要多少次旋转
    let rotationsTops = 0, rotationsBottoms = 0;

    // 遍历骨牌判断是否能完成任务(在 tops 中完成或者在 bottoms 中完成)
    for (let i = 0; i < len; i++) {
        if (tops[i] != x && bottoms[i] != x) {
            // 如果当前多米诺骨牌上没有数字 x,那么不可能完成任务
            return -1;
        } else if (tops[i] != x) {
            // 如果当前多米诺骨牌上 tops[i] 不是 x,那么 rotationsTops 需要 +1 (旋转一次)
            rotationsTops++;
        } else if (bottoms[i] != x) {
            // 如果当前多米诺骨牌上 bottoms[i] 不是 x,那么 rotationsBottoms 需要+1 (旋转一次)
            rotationsBottoms++;
        }
    }

    // 返回最小旋转次数
    return Math.min(rotationsTops, rotationsBottoms);
}

cpp 解法, 执行用时: 84 ms, 内存消耗: 109.2 MB, 提交时间: 2023-09-23 00:34:56

class Solution {
    public:
    /*
    Return min number of rotations 
    if one could make all elements in A or B equal to x.
    Else return -1.
    */
    int check(int x, vector<int>& A, vector<int>& B, int n) {
        // how many rotations should be done
        // to have all elements in A equal to x
        // and to have all elements in B equal to x
        int rotations_a = 0, rotations_b = 0;
        for (int i = 0; i < n; i++) {
            // rotations coudn't be done
            if (A[i] != x && B[i] != x) return -1;
            // A[i] != x and B[i] == x
            else if (A[i] != x) rotations_a++;
            // A[i] == x and B[i] != x    
            else if (B[i] != x) rotations_b++;
        }
        // min number of rotations to have all
        // elements equal to x in A or B
        return min(rotations_a, rotations_b);
    }

    int minDominoRotations(vector<int>& A, vector<int>& B) {
        int n = A.size();
        int rotations = check(A[0], B, A, n);
        // If one could make all elements in A or B equal to A[0]
        if (rotations != -1 || A[0] == B[0]) return rotations;
        // If one could make all elements in A or B equal to B[0]
        else return check(B[0], B, A, n);
    }
};

java 解法, 执行用时: 3 ms, 内存消耗: 47.7 MB, 提交时间: 2023-09-23 00:34:45

class Solution {
    /*
    Return min number of rotations 
    if one could make all elements in A or B equal to x.
    Else return -1.
    */
    public int check(int x, int[] A, int[] B, int n) {
        // how many rotations should be done
        // to have all elements in A equal to x
        // and to have all elements in B equal to x
        int rotations_a = 0, rotations_b = 0;
        for (int i = 0; i < n; i++) {
            // rotations coudn't be done
            if (A[i] != x && B[i] != x) return -1;
            // A[i] != x and B[i] == x
            else if (A[i] != x) rotations_a++;
            // A[i] == x and B[i] != x    
            else if (B[i] != x) rotations_b++;
        }
        // min number of rotations to have all
        // elements equal to x in A or B
        return Math.min(rotations_a, rotations_b);
    }

    public int minDominoRotations(int[] A, int[] B) {
        int n = A.length;
        int rotations = check(A[0], B, A, n);
        // If one could make all elements in A or B equal to A[0]
        if (rotations != -1 || A[0] == B[0]) return rotations;
        // If one could make all elements in A or B equal to B[0]
        else return check(B[0], B, A, n);
    }
}

上一题