LeetCode1007. 行相等的最少多米诺旋转
在一排多米诺骨牌中,tops[i] 和 bottoms[i] 分别代表第 i 个多米诺骨牌的上半部分和下半部分。(一个多米诺是两个从 1 到 6 的数字同列平铺形成的 —— 该平铺的每一半上都有一个数字。)
我们可以旋转第 i 张多米诺,使得 tops[i] 和 bottoms[i] 的值交换。
返回能使 tops 中所有值或者 bottoms 中所有值都相同的最小旋转次数。
如果无法做到,返回 -1.
示例 1:
输入: tops = [2,1,2,4,2,2], bottoms = [5,2,6,2,3,2]
输出: 2
解释:
图一表示:在我们旋转之前, tops 和 bottoms 给出的多米诺牌。
如果我们旋转第二个和第四个多米诺骨牌,我们可以使上面一行中的每个值都等于 2,如图二所示。
示例 2:
输入: tops = [3,5,1,2,3], bottoms = [3,6,3,3,4]
输出: -1
解释: 在这种情况下,不可能旋转多米诺牌使一行的值相等。
提示:
bottoms.length == tops.length1 <= tops[i], bottoms[i] <= 6
思路分析
翻转 a = 以第一排为主,翻转 不能反转的返回Integer.MAX_VALUE 如果可以翻转 把第一排的数字放入第二排 看是否可以翻转 对比两次那个小 返回 b = 以第二排为主,翻转 不能反转的返回Integer.MAX_VALUE 如果可以翻转 把第一排的数字放入第一排 看是否可以翻转 对比两次那个小 返回
用最少的旋转次数,使A或B的数字一样 首先要使A或B数字一样,那么这个数字的数量必须大于等于A或B(A和B长度是一样的),即大于等于总长度的一半,然后,必须每一列都包含这个数字(假设为X),这两个条件都满足,说明可以达成目标 最小的旋转次数就是往A旋转还是往B旋转,遍历A和B的每列,只要不等于X,那么就需要旋转一次
算法代码
public int minDominoRotations(int[] A, int[] B) {
int[] countArr = new int[7];
for (int a: A) {
countArr[a] ++;
}
for (int b: B) {
countArr[b] ++;
}
int num = -1;
//找到数量最多的数字,如果这个数字大于等于A的长度,就是最多的(已经超过总数量的一半了)
for (int i = 0; i < countArr.length; i++) {
if (countArr[i] >= A.length) {
num = i;
break;
}
}
if (num == -1) {
return -1;
}
int counta = 0;
int countb = 0;
//计算A和B数组各自需要旋转的次数
for (int i = 0; i < A.length; i++) {
if (A[i] != num && B[i] != num) {
return -1;
}
if (A[i] == num && B[i] != num) {
countb++;
} else if (A[i] != num && B[i] == num) {
counta++;
}
}
//返回最小值即可
return counta < countb ? counta : countb;
}
结果详情
算法复杂度
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!