【每日一题Day142】LC1590使数组和能被 P 整除 | 前缀和+哈希表
创始人
2024-06-01 03:22:44

使数组和能被 P 整除【LC1590】

给你一个正整数数组 nums,请你移除 最短 子数组(可以为 ),使得剩余元素的 能被 p 整除。 不允许 将整个数组都移除。

请你返回你需要移除的最短子数组的长度,如果无法满足题目要求,返回 -1

子数组 定义为原数组中连续的一组元素。

这种只差一点的感觉 真难受

  • 思路

    假设数组总和为sumsumsum,删除的数组范围为[left,right][left,right][left,right],那么可以通过前缀和数组计算出删除数组的和,记为yyy,此时剩余元素之和为sum−ysum-ysum−y,如果剩余元素之和能够整除p,那么此时满足
    (sum−y)%p=0y=sum%p(sum-y)\%p=0 \\y = sum \% p (sum−y)%p=0y=sum%p
    通过前缀和数组可得
    pre[right]−pre[left]=sum%ppre[left]=(pre[right]−sum)%ppre[right]-pre[left] = sum \% p \\pre[left] =(pre[right]-sum) \% p pre[right]−pre[left]=sum%ppre[left]=(pre[right]−sum)%p
    因此我们可以将前缀和放入哈希表中,哈希表存放前缀和及其对应的下标,然后对于每个right,查找是否有符合的left,有则更新最小长度

  • 实现

    为了防止越界,前缀和数组记录对p取余的结果

    class Solution {public int minSubarray(int[] nums, int p) {int n = nums.length, ans = n;var s = new int[n + 1];for (int i = 0; i < n; ++i)s[i + 1] = (s[i] + nums[i]) % p;int x = s[n];if (x == 0) return 0; // 移除空子数组(这行可以不要)var last = new HashMap();for (int i = 0; i <= n; ++i) {last.put(s[i], i);// 如果不存在,-n 可以保证 i-j >= nint j = last.getOrDefault((s[i] - x + p) % p, -n);ans = Math.min(ans, i - j);}return ans < n ? ans : -1;}
    }作者:灵茶山艾府
    链接:https://leetcode.cn/problems/make-sum-divisible-by-p/solutions/2158435/tao-lu-qian-zhui-he-ha-xi-biao-pythonjav-rzl0/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    • 复杂度
      • 时间复杂度:O(n)O(n)O(n)
      • 空间复杂度:O(n)O(n)O(n)

相关内容

热门资讯

苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...