A和B两个数组中的所有值都在[1,6]。每次操作中,你可以选择 任意 数组中的任意一个整数,将它变成 1 到 6 之间 任意 的值(包含 1 和 6)。请返回使 A中所有数的和与 B 中所有数的和相等的最少操作次数。无解返回 -1 。
思路:约定sum(A)<sum(B),sA∈[n,6n],sA∈[m,6m]:
- 有解则,sA和sB有交集,也就是 6n<=m
- 否则无解
class Solution:
def minOperations(self, A: List[int], B: List[int]) -> int:
def get(x, m: List[int]): #得到距离x需要的操作次数
s, ans = 0, 0
for i in range(1,7): s += i * m[i]
d = abs(x - s)
if s < x:
for i in range(1,6):
a = 6 - i
if a * m[i] >= d: return ans + math.ceil(d / a)
ans, d = ans + m[i], d - a * m[i]
else:
for i in range(6,1,-1):
a = i - 1
if a * m[i] >= d: return ans + math.ceil(d / a)
ans, d = ans + m[i], d - a * m[i]
return ans
n, m = len(A), len(B)
if n > m: return self.minOperations(B, A)
if 6*n < m: return -1
m1, m2 = [0]*7, [0]*7
for x in A: m1[x] = m1[x] + 1
for x in B: m2[x] = m2[x] + 1
ans = float('inf')
for x in range(m, 6*n+1):
ans = min(ans, get(x, m1) + get(x, m2))
return ans
其实 get 函数可以用逻辑优化掉的...