python提交中击败了100%的用户!有史以来第一次。。稍微记录一下此刻的心情。
话不多说直接上代码,解释全在注释里:
class Solution(object):
def maxSumDivThree(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l1 = []
l2 = []
res = 0 #能被三整除的数字的加和
la = 0 #用于统计不能被3整除的数据
for i in range(len(nums)):#把列表的数字归类
if nums[i] % 3 == 0:
res += nums[i]
elif nums[i] % 3 == 1:#如果余数为1,插入l1中
l1.append(nums[i])
la += nums[i]
else:#余数为2,插入l2中
l2.append(nums[i])
la += nums[i]
if la%3==1:#余数为1,可以选择删除一个1的值,也可以选择删除2个2的值
aa1 = 99999#因为条件说的最大的数不超过4*10**4,所以弄了个99999>4*10**4
aa2 = [99999, 99999]
res+=la#所有数据都求和,方便后面计算
#这里加la是好像很鸡肋,为什么不在上面分类时就?第一时间就想记录下来所以就没改
if len(l1)>=1:#如果有1个以上的余数为1的数,选个最小的出来
for i in l1:
if aa1 > i:
aa1 = i
if len(l2)>=2:#如果有2个以上的余数为2的数,选2个最小的出来
for i in l2:
if aa2[1] > i:
aa2[1] = i
if aa2[0]>aa2[1]:#始终保持0号最小
aa2[0],aa2[1] = aa2[1],aa2[0]
if aa1 == 99999 and aa2[0] == 99999:
#如果上文两个条件都不满足,但la%3==1就说明此时没法挑出能够让res减去的值来让res被3整除,所以直接返回0
return 0
if aa2[0] + aa2[1] < aa1:#选出两种方案中最小的那个,让res减去,此时余数刚好为0
res -= aa2[0] + aa2[1]
else:
res -= aa1
elif la%3 == 2:#同上,此时就是需要减去两个余数为1的数或者1个余数为2的值
aa1 = [99999, 99999]
aa2 = 99999
res+=la
if len(l1)>=2:#删两个1
for i in l1:
if aa1[1] > i:
aa1[1] = i
if aa1[0] > aa1[1]: # 始终保持0号最小
aa1[0], aa1[1] = aa1[1], aa1[0]
if len(l2)>0:
for i in l2:
if aa2>i:
aa2=i
if aa2 == 99999 and aa1[0] == 99999:
return 0
if aa1[0]+aa1[1] < aa2:
res -= aa1[0] + aa1[1]
else:
res -= aa2
elif la%3==0:
#加此if分支是因为如果la也能被3整除,将la加到res中直接返回就行,不需要进行任何处理
return res+la
return res
ab = Solution()
print(ab.maxSumDivThree([3,3,3,1,2]))
总结:
将集合能被3整除的数加和到res
中,不能被3整除的加到la
中,再判断la
除以3的余数来判断到底该减去min(一个余数为2的数,两个余数为1的数)
还是min(一个余数为1的数,两个余数为2的数)
,或者是直接输出res+la
。
虽然内存耗得多(用了两个列表保存),但是快不快就完了