题目
思路
首先要考虑返回-1的情况:对于长度为n的数组,其数组所有数之和的取值范围为[n,6n]。设另一个数组的长度为x,则不可能的情况为6x<n或者6n<x。
接下来考虑一般情况的解法。由于题目要求修改次数最少,因此考虑贪心思路的话,一般会想到对于和小的那个数组来说,尽量增长小的数(因为小的数增长有较大的空间,对和的贡献较大)。同理,对于和较大的数组,则尽量减小大的数,注意对于和大的数组减小元素可以认为是增加和小的数组的元素,因此可以对两个数组进行统一的统计。具体做法给定一个字典或者列表并对两个数组遍历一遍,对于和小的数组,统计6-x(即增加量)出现的次数;对于和大的数组则统计x-1出现的次数。之后对统计字典或者列表依据键值从大到小遍历,用两个数组和的差做被减数,每次运算统计答案。当和的差小于或等于0时(小于0的话说明可以增加一个更小量使得两个和相等,但不影响最后的结果),即退出循环,统计答案。
class Solution:
def minOperations(self, nums1: List[int], nums2: List[int]) -> int:
summ1=sum(nums1)
summ2=sum(nums2)
if summ1==summ2:
return 0
n1=len(nums1)
n2=len(nums2)
if n1>6*n2 or n2>6*n1:
return -1
#0print(2)
if summ1<summ2:
ans=0
diff={}
cur=summ2-summ1
for temp in nums1:
diff[6-temp]=diff.get(6-temp,0)+1
for temp in nums2:
diff[temp-1]=diff.get(temp-1,0)+1
#sorted(diff)
for i in range(5,-1,-1):
if i==0:
return -1
if i*diff.get(i,0)<cur:
ans+=diff.get(i,0)
cur-=i*diff.get(i,0)
else:
if not cur%i:
ans+=cur//i
else:
ans+=cur//i+1
return ans
else:
ans=0
diff={}
cur=summ1-summ2
for temp in nums2:
diff[6-temp]=diff.get(6-temp,0)+1
for temp in nums1:
diff[temp-1]=diff.get(temp-1,0)+1
for i in range(5,-1,-1):
if i==0:
return -1
if i*diff.get(i,0)<cur:
ans+=diff.get(i,0)
cur-=i*diff.get(i,0)
else:
if not cur%i:
#print(cur//diff[i])
ans+=cur//i
else:
#print(cur,diff[i],cur//diff[i])
ans+=cur//i+1
return ans