指尖划过的轨迹,藏着最细腻的答案~
题目:
给你一个下标从 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 。
提示:
- 1 <= nums.length, value <= <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 0 5 10^5 </math>105
- <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 0 9 10^9 </math>109 <= nums[i] <= <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 0 9 10^9 </math>109
分析:
题目意思即对于数组nums
中的每一个数字加减任意次value
,寻找从0开始的没有出现的数字。
我们比较容易得可以想到余数,那怎么使用这个余数呢?如果nums[i]
对value
取模的值为0,说明0出现,如果nums[j]
对value
取模的值为1,说明1出现,以此类推......
那如果nums[t]
对value
取模的值再次出现0,但0已经出现过了,此时说明value
出现......value+1
出现,以此类推,直到没有连续的值ans出现,即为答案。
需要注意负数的处理:将负数的取模映射到[0, m-1]
中,可以使用公式: <math xmlns="http://www.w3.org/1998/Math/MathML"> x % m o d + m o d x \% mod + mod </math>x%mod+mod,那如果是正数,上面公式就不适配,需要判断正负,更通用的公式如下: <math xmlns="http://www.w3.org/1998/Math/MathML"> ( x % m o d + m o d ) % m o d (x \% mod + mod) \% mod </math>(x%mod+mod)%mod
AC代码:
c++
class Solution {
public:
int findSmallestInteger(vector<int>& nums, int value) {
unordered_map<int, int> cnt;
for (int num : nums) {
cnt[(num % value + value) % value]++;
}
int ans = 0;
while (cnt[ans % value]-- > 0) {
ans++;
}
return ans;
}
};