在一排多米诺骨牌中,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
解题思路
首先,我们可以想到一个很朴素的思想,就是统计A
和B
中最多出现的元素,然后再比较二者那个大,取其大者,最后判断其他元素不符的位置是否可以通过交换实现匹配。
from collections import Counter
class Solution:
def minDominoRotations(self, A: List[int], B: List[int]) -> int:
a, b = len(A), len(B)
ca, cb = Counter(A), Counter(B)
va, vb = ca.most_common(1), cb.most_common(1)
res1, res2 = 0, 0
if va[0][1] > vb[0][1]:
for i in range(a):
if A[i] != va[0][0]:
if B[i] == va[0][0]:
res1 += 1
else:
return -1
return res1
else:
for i in range(b):
if B[i] != vb[0][0]:
if A[i] == vb[0][0]:
res2 += 1
else:
return -1
return res2
return -1
非常幸运通过了测试,但是为什么这样做是对的呢?我举一个例子,如果A=[3,3,3,2,2]
,此时A
中最多的元素是3
,假设我们最后的结果不是3
而是2
,那么B
中必然会有3
个2
,也就是此时的众数应该是2
,这就是我们题设相违背了。所以我们推测出我们前面的想法应该是对的,但是具体的数学证明就不说了。
当然我们也可以通过暴力法,因为总共只有6
个数。我们首先判断1~6
这几个数是不是可以得到结果,然后从中取最下的反转次数即可。
class Solution:
def minDominoRotations(self, A: List[int], B: List[int]) -> int:
for i in range(1,7):
if all(i == a or i == b for a,b in zip(A,B)):
return min(len(A)-A.count(i),len(B)-B.count(i))
return -1
但是上面的算法都没有符合题目的本意,我们思考一个多米诺骨牌,无非就是将一个牌向后推的过程,所以我们这里只有两种情况,一种是A
的首元素向后,另一种是B
的是元素向后。
接着就是向后的过程,只有相同的元素我们的牌才会倒下,我们此时,只需通过两个遍历记录我们交替变更的次数(因为有两种情况,一种是A
中的元素交换到B
中,另一种是B
中的元素交换到A
中),最后去二者的最小值即可(如果能推到最后一个牌的话)。否则,GG!!!
class Solution:
def minDominoRotations(self, A: List[int], B: List[int]) -> int:
a, b, n = 0, 0, len(A)
for i in range(n):
if A[i] != A[0] and B[i] != A[0]:
break
if A[i] != A[0]:
a += 1
if B[i] != A[0]:
b += 1
if i == n - 1:
return min(a, b)
a, b = 0, 0
for i in range(n):
if A[i] != B[0] and B[i] != B[0]:
break
if A[i] != B[0]:
a += 1
if B[i] != B[0]:
b += 1
if i == n - 1:
return min(a, b)
return -1
reference:
https://leetcode.com/problems/minimum-domino-rotations-for-equal-row/submissions/
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!