LeetCode 1007. 行相等的最少多米诺旋转 C++描述

1007. 行相等的最少多米诺旋转 C++描述

在一排多米诺骨牌中,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 <= A[i], B[i] <= 6
2 <= A.length == B.length <= 20000

题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-domino-rotations-for-equal-row

很久没写力扣的题目了,自己写只写出了一个暴力,勉强过关,代码如下:

class Solution {
public:
    int minDominoRotations(vector<int>& A, vector<int>& B) {
        int ans = A.size()+10;
        int store[7] = {0};//记录各有多少个数字
        for(int i = 0;i < A.size(); i++){
            if(A[i] == B[i]){
                store[A[i]]++;
            }else{
                store[A[i]]++;
                store[B[i]]++;
            }
        }
        for(int i = 1;i <= 6; i++){
            if(store[i] < A.size())
                continue;
            int cnt_1,cnt_2,j;
            cnt_1 = cnt_2 = 0;
            for(j = 0; j < A.size(); j++){
                if(B[j] != i && A[j] != i){
                    break;;
                }
                if(B[j] == i && A[j] != i){
                    cnt_1++;
                }
                if(A[j] == i && B[j] != i){
                    cnt_2++;
                }
            }
            if(j == A.size() && ans > (cnt_1 > cnt_2 ? cnt_2 : cnt_1)){
                //将较小的值赋给ans
                ans = (cnt_1 > cnt_2 ? cnt_2 : cnt_1);
            }
        }
        return ans == A.size()+10 ? -1 : ans;
    }
};

看了官方解答之后恍然大悟,其实没必要暴力,只需要考虑第一个牌的情形进行贪心就好了,代码如下:

class Solution {
public:
    int check(int x, vector<int>& A, vector<int>& B, int n) {
        int rotations_a = 0, rotations_b = 0;//记录转换A和B的值,分别初始化为0
        for (int i = 0; i < n; i++) {//遍历vector
            if (A[i] != x && B[i] != x) return -1;//如果A[i]和B[i]同时不等于i,则此值无法达到要求,返回-1
            else if (A[i] != x) rotations_a++;//如果A[i] != x,即需要转换A的时候,记录A的rotations_a++
            else if (B[i] != x) rotations_b++;//如果B[i] != x,即需要转换B的时候,记录A的rotations_b++
        }
        return min(rotations_a, rotations_b);//返回两个中的小的值
    }

    int minDominoRotations(vector<int>& A, vector<int>& B) {
        int n = A.size();//n为A的长度
        int rotations = check(A[0], B, A, n);//以A[0]的值为数值检测能否完成
        if (rotations != -1 || A[0] == B[0]) return rotations;//当返回值不是-1的时候,即能够完成的时候返回该值,当A[0] 和 B[0]相同时,即使用A[0]为底和使用B[0]为底一样的时候,直接返回值,不需要考虑B[0]为底的情况
        else return check(B[0], B, A, n);//否则返回以B[0]为底的值
    }
};





发布了153 篇原创文章 · 获赞 140 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_43422111/article/details/105080575
今日推荐