leetcode 2598 执行操作后最大MEX
2598. 执行操作后的最大 MEX
题目描述如下
给你一个下标从 0 开始的整数数组 nums 和一个整数 value 。
在一步操作中,你可以对 nums 中的任一元素加上或减去 value 。
例如,如果 nums = [1,2,3] 且 value = 2 ,你可以选择 nums[0] 减去 value ,得到 nums = [-1,2,3] 。
数组的 MEX (minimum excluded) 是指其中数组中缺失的最小非负整数。
例如,[-1,2,3] 的 MEX 是 0 ,而 [1,0,3] 的 MEX 是 2 。
返回在执行上述操作 任意次 后,nums 的最大 MEX 。
示例 1:输入:nums = [1,-10,7,13,6,8], value = 5
输出:4
解释:执行下述操作可以得到这一结果:
- nums[1] 加上 value 两次,nums = [1,0,7,13,6,8]
- nums[2] 减去 value 一次,nums = [1,0,2,13,6,8]
- nums[3] 减去 value 两次,nums = [1,0,2,3,6,8]
nums 的 MEX 是 4 。可以证明 4 是可以取到的最大 MEX 。
示例 2:输入:nums = [1,-10,7,13,6,8], value = 7
输出:2
解释:执行下述操作可以得到这一结果:
- nums[2] 减去 value 一次,nums = [1,-10,0,13,6,8]
nums 的 MEX 是 2 。可以证明 2 是可以取到的最大 MEX 。
乍一看完全不理解,怎么又是任意次数又是两个变量的,什么神奇的问题,但是我们做题还是要找一找规律最重要的.nums中的元素减value,这一点应该可以想到余数的意味,但是光想到取余还完全不够,因为我们首先要求MEX,而且还要的是最大MEX.
最好的办法还是暴力穷举一下规律.
对于nums = [1,-10,7,13,6,8], value = 5来说,我们通过加减操作,变为取余操作
分别为
1
0
2
3
1
3
MEX是4,与余数的数量也是对不上的
加减任意次的意思不就是可以最终变为相同的元素值,也就是说1%5=1,可以覆盖1,6,11,16这些除以5余1的非负整数.
统计一下余数出现的次数,分别是:
1 2次
0 1次
2 1次
3 2次
我们从最小的整数开始,找第一个覆盖不了的数就是MEX
这个数定义为m:
检查的数 m m 的余数 r = m%5 m 是该余数的第几个数(k = m//5) 需要该余数的元素数量 ≥ k+1? 能否覆盖?
0 0 0//5 = 0 → 需要 ≥ 1 个 余数 0 有 1 个 → 够 能
1 1 1//5 = 0 → 需要 ≥ 1 个 余数 1 有 2 个 → 够 能
2 2 2//5 = 0 → 需要 ≥ 1 个 余数 2 有 1 个 → 够 能
3 3 3//5 = 0 → 需要 ≥ 1 个 余数 3 有 2 个 → 够 能
4 4 4//5 = 0 → 需要 ≥ 1 个 余数 4 有 0 个 → 不够 不能
检查到4是不能的.
再强调一下这个逻辑:
余数为 r 的元素,能覆盖的数是 r, r+5, r+10, …, r+5k(共 k+1 个数),前提是有至少 k+1 个该余数的元素。
当某个余数 r 的元素数量不足时,对应的 m = 5k + r 就是 MEX。
这里余数 4 的元素数量为 0,连 k=0(即 m=4)都覆盖不了,所以 MEX 是 4。
(貌似就是一个余数数量的问题…)
解答
class Solution:def findSmallestInteger(self, nums: List[int], value: int) -> int:# 统计每个余数出现的次数# counts = defaultdict(int)counts = {} # 普通字典需要初始化次数for num in nums:rem = num % valueif rem not in counts:counts[rem] = 0 # 初始化counts[rem] += 1for k in range(len(nums)+1):# 最开始k=0for r in range(value): # 检查r,直接从value中的正整数遍历#r=0m = k*value+rif counts.get(r, 0) <= k:return mreturn len(nums)
先到这吧,我其实没有太理解…
r:非负整数 m 对 value 的余数(r = m % value)。
k:m 是 “余数为 r 的数” 中的第 k+1 个(k = m // value)。
counts:统计每个余数出现次数的字典(键是余数 r,值是该余数的元素数量)。
余数为 r 的元素,能覆盖的数是:r, r+value, r+2value, …, r+kvalue(共 k+1 个数)。要覆盖其中的第 k+1 个数(即 m = r + k*value),需要至少 k+1 个该余数的元素(每个元素负责覆盖一个数)。
如果:
元素数量 counts[r] > k → 数量 ≥ k+1 → 能覆盖 m;
元素数量 counts[r] <= k → 数量 < k+1 → 不能覆盖 m(此时 m 就是 MEX)。
结合例子看(value=5,m=4)
m=4,r = 4%5 = 4,k = 4//5 = 0。
counts.get(4, 0) → 字典中没有余数 4,返回默认值 0。
条件 0 <= 0 成立 → 说明余数 4 的元素数量不足(0 个 < 需 1 个),无法覆盖 m=4 → 4 是 MEX。