2023-07-18:给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空),

使得剩余元素的 和 能被 p 整除。 不允许 将整个数组都移除。

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

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

输入:nums = [3,1,4,2], p = 6。

输出:1。

答案2023-07-18:

大体过程如下:

1.计算整个数组的和对p取余,得到allMod

2.初始化一个空的映射m,并将映射中键为0,值为-1。该映射用于记录前缀和的某个余数最晚出现的位置。

3.初始化一个变量ans,表示最短子数组的长度,初值为无穷大。

4.初始化一个变量curMod,表示当前的前缀和余数,初值为0。

5.初始化一个变量find,表示要查找的余数,初值为0。

6.遍历数组nums中的每个元素:

  • 将当前元素加到curMod中,并对p取余,得到当前前缀和的余数curMod

  • 计算要查找的余数find = (curMod - allMod + p) % p

  • 在映射m中查找余数为find的键,如果存在则计算当前位置与查找到的位置之差,并更新ans为较小的值。

  • 更新映射m,将当前余数curMod存储到映射中。

7.如果ans没有被更新,则返回-1,否则返回ans

代码的时间复杂度为O(n),其中n是数组nums的长度。这是因为在遍历数组nums的过程中,需要进行常数时间的操作,包括计算前缀和的余数、更新映射m等。

代码的空间复杂度为O(n),其中n是数组nums的长度。这是因为需要使用一个映射m来记录前缀和的余数及其最晚出现的位置,映射m的大小不会超过数组的长度n。此外,还需要用几个额外的变量来存储一些中间结果,这些变量的空间占用也是常数级别的,不会随着输入规模n的增大而增加。

go完整代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func minSubarray(nums []int, p int) int {
  6. n := len(nums)
  7. // 求出整体的余数
  8. allMod := 0
  9. for _, num := range nums {
  10. allMod = (allMod + num) % p
  11. }
  12. if allMod == 0 {
  13. return 0
  14. }
  15. // 记录前缀和的某个余数,最晚出现的位置
  16. // 看课!然后看接下来的代码
  17. m := make(map[int]int)
  18. m[0] = -1
  19. ans := 1<<31 - 1
  20. curMod := 0
  21. var find int
  22. for i := 0; i < n; i++ {
  23. // 0...i 累加和的余数
  24. curMod = (curMod + nums[i]) % p
  25. // 如果p = 7,整体余数2,当前余数5,那么找之前的部分余数是3
  26. // 如果p = 7,整体余数2,当前余数1,那么找之前的部分余数是6
  27. // 整体变成下面的公式,可以自己带入各种情况验证
  28. find = (curMod - allMod + p) % p
  29. val, ok := m[find]
  30. if ok {
  31. if i != n-1 || val != -1 {
  32. // 防止删掉整体!
  33. // ...i(n-1)
  34. ans = min(ans, i-val)
  35. }
  36. }
  37. m[curMod] = i
  38. }
  39. if ans == 1<<31-1 {
  40. return -1
  41. }
  42. return ans
  43. }
  44. func min(a, b int) int {
  45. if a < b {
  46. return a
  47. }
  48. return b
  49. }
  50. func main() {
  51. nums := []int{3, 1, 4, 2}
  52. p := 6
  53. result := minSubarray(nums, p)
  54. fmt.Println(result)
  55. }

rust代码如下:

  1. use std::collections::HashMap;
  2. fn min_subarray(nums: Vec<i32>, p: i32) -> i32 {
  3. let n = nums.len();
  4. // 求出整体的余数
  5. let all_mod: i32 = nums.iter().sum::<i32>() % p;
  6. if all_mod == 0 {
  7. return 0;
  8. }
  9. // 记录前缀和的某个余数,最晚出现的位置
  10. let mut map: HashMap<i32, i32> = HashMap::new();
  11. map.insert(0, -1);
  12. let mut ans = i32::max_value();
  13. let mut cur_mod = 0;
  14. let mut find;
  15. for i in 0..n {
  16. // 0...i 累加和的余数
  17. cur_mod = (cur_mod + nums[i]) % p;
  18. // 如果p = 7,整体余数2,当前余数5,那么找之前的部分余数是3
  19. // 如果p = 7,整体余数2,当前余数1,那么找之前的部分余数是6
  20. // 整体变成下面的公式,可以自己带入各种情况验证
  21. find = (cur_mod - all_mod + p) % p;
  22. if map.contains_key(&find) {
  23. if i != n - 1 || map[&find] != -1 {
  24. // 防止删掉整体!
  25. // ...i(n-1)
  26. ans = ans.min(i as i32 - map[&find]);
  27. }
  28. }
  29. map.insert(cur_mod, i as i32);
  30. }
  31. return if ans == i32::max_value() { -1 } else { ans };
  32. }
  33. fn main() {
  34. let nums = vec![3, 1, 4, 2];
  35. let p = 6;
  36. let result = min_subarray(nums, p);
  37. println!("{}", result);
  38. }

c++完整代码如下:

  1. #include <iostream>
  2. #include <vector>
  3. #include <unordered_map>
  4. using namespace std;
  5. int minSubarray(vector<int>& nums, int p) {
  6. int n = nums.size();
  7. // 求出整体的余数
  8. int allMod = 0;
  9. for (int num : nums) {
  10. allMod = (allMod + num) % p;
  11. }
  12. if (allMod == 0) {
  13. return 0;
  14. }
  15. // 记录前缀和的某个余数,最晚出现的位置
  16. // 看课!然后看接下来的代码
  17. unordered_map<int, int> map;
  18. map[0] = -1;
  19. int ans = INT_MAX;
  20. int curMod = 0, find;
  21. for (int i = 0; i < n; i++) {
  22. // 0...i 累加和的余数
  23. curMod = (curMod + nums[i]) % p;
  24. // 如果p = 7,整体余数2,当前余数5,那么找之前的部分余数是3
  25. // 如果p = 7,整体余数2,当前余数1,那么找之前的部分余数是6
  26. // 整体变成下面的公式,可以自己带入各种情况验证
  27. find = (curMod - allMod + p) % p;
  28. if (map.find(find) != map.end()) {
  29. if (i != n - 1 || map[find] != -1) {
  30. // 防止删掉整体!
  31. // ...i(n-1)
  32. ans = min(ans, i - map[find]);
  33. }
  34. }
  35. map[curMod] = i;
  36. }
  37. return (ans == INT_MAX) ? -1 : ans;
  38. }
  39. int main() {
  40. vector<int> nums = { 3, 1, 4, 2 };
  41. int p = 6;
  42. int result = minSubarray(nums, p);
  43. cout << "Result: " << result << endl;
  44. return 0;
  45. }

c完整代码如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4. int minSubarray(int* nums, int numsSize, int p) {
  5. int n = numsSize;
  6. // 求出整体的余数
  7. int allMod = 0;
  8. for (int i = 0; i < n; i++) {
  9. allMod = (allMod + nums[i]) % p;
  10. }
  11. if (allMod == 0) {
  12. return 0;
  13. }
  14. // 记录前缀和的某个余数,最晚出现的位置
  15. // 看课!然后看接下来的代码
  16. int* map = (int*)malloc(sizeof(int) * p);
  17. for (int i = 0; i < p; i++) {
  18. map[i] = -1;
  19. }
  20. map[0] = -1;
  21. int ans = INT_MAX;
  22. int curMod = 0, find;
  23. for (int i = 0; i < n; i++) {
  24. // 0...i 累加和的余数
  25. curMod = (curMod + nums[i]) % p;
  26. // 如果p = 7,整体余数2,当前余数5,那么找之前的部分余数是3
  27. // 如果p = 7,整体余数2,当前余数1,那么找之前的部分余数是6
  28. // 整体变成下面的公式,可以自己带入各种情况验证
  29. find = (curMod - allMod + p) % p;
  30. if (map[find] != -1) {
  31. if (i != n - 1 || map[find] != -1) {
  32. // 防止删掉整体!
  33. // ...i(n-1)
  34. ans = (ans < i - map[find]) ? ans : i - map[find];
  35. }
  36. }
  37. map[curMod] = i;
  38. }
  39. free(map);
  40. return (ans == INT_MAX) ? -1 : ans;
  41. }
  42. int main() {
  43. int nums[] = { 3, 1, 4, 2 };
  44. int p = 6;
  45. int numsSize = sizeof(nums) / sizeof(nums[0]);
  46. int result = minSubarray(nums, numsSize, p);
  47. printf("Result: %d\n", result);
  48. return 0;
  49. }

2023-07-18:给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空), 使得剩余元素的 和 能被 p 整除。 不允许 将整个数组都移除。 请你返回你需要移除的最短子数组的长度,如果的更多相关文章

  1. 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。

    /** * 给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标. * * 你可以假设每种输入只会对应一个答案.但是,数组中 ...

  2. 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。

    谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...

  3. 刷题之给定一个整数数组 nums 和一个目标值 taget,请你在该数组中找出和为目标值的那 两个 整数

    今天下午,看了一会github,想刷个题呢,就翻出来了刷点题提高自己的实际中的解决问题的能力,在面试的过程中,我们发现,其实很多时候,面试官 给我们的题,其实也是有一定的随机性的,所以我们要多刷更多的 ...

  4. 最接近的三数之和(给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数, 使得它们的和与 target 最接近。返回这三个数的和)

    例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2). 思路:首先对数组进行排序     ...

  5. 给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。-----力扣

    给定长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积. 示例: 输入: [1 ...

  6. 给定一个整数数组 nums 和一个目标值 target,求nums和为target的两个数的下表

    这个是来自力扣上的一道c++算法题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案 ...

  7. 从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。

    Scanner sc=new Scanner(System.in); System.out.println("请输入一个正整数:"); int ss=sc.nextInt(); i ...

  8. 17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行。请采用循环控制语句来实现。 (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和。) 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1

    17.从键盘上输入一个正整数n,请按照以下五行杨辉三角形的显示方式, 输出杨辉三角形的前n行.请采用循环控制语句来实现. (三角形腰上的数为1,其他位置的数为其上一行相邻两个数之和.) 1 1 1 1 ...

  9. 在排序数组中查找元素的第一个和最后一个位置(给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。)

    示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出 ...

  10. 刷题3:给定一个数组 nums,判断 nums 中是否存在三个下标 a,b,c数相加等于targe且a,b,c不相等

    题目: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,下标 ,a ,b , c 对应数相加等于 targe 找出所有满足条件且不重复的三元组下标 解析: ...

随机推荐

  1. RDIFramework.NET代码生成器全新V5.0版本发布

    RDIFramework.NET代码生成器介绍 RDIFramework.NET代码生成器,代码.文档一键生成. RDIFramework.NET代码生成器集代码生成.各数据库对象文档生成.数据库常用 ...

  2. Redis分布式锁这样用,有坑?

    背景 在微服务项目中,大家都会去使用到分布式锁,一般也是使用Redis去实现,使用RedisTemplate.Redisson.RedisLockRegistry都行,公司的项目中,使用的是Redis ...

  3. Go/Python gRPC实践

    gRPC框架 & ProtoBuf 安装相关工具: pip3 install grpcio pip3 install grpcio-tools protobuf3有自己专门的定义的格式,基于此 ...

  4. 迁移学习(PAT)《Pairwise Adversarial Training for Unsupervised Class-imbalanced Domain Adaptation》

    论文信息 论文标题:Pairwise Adversarial Training for Unsupervised Class-imbalanced Domain Adaptation论文作者:Weil ...

  5. vue3.0

    https://www.yuque.com/gdnnth/vue-v3 http://www.liulongbin.top:8085/#/ https://www.yuque.com/woniuppp ...

  6. 中国剩余定理(CRT)学习笔记

    约定 \(A\perp B\) 表示 \(\gcd(A,B)=1\). \(A\mid B\) 表示 \(B\equiv 0\pmod{A}(A\neq0)\). 引入 考虑以下这道题: 有物不知其數 ...

  7. 深入理解 python 虚拟机:描述器的王炸应用-property、staticmethod 和 classmehtod

    深入理解 python 虚拟机:描述器的王炸应用-property.staticmethod 和 classmehtod 在本篇文章当中主要给大家介绍描述器在 python 语言当中有哪些应用,主要介 ...

  8. 2023-04-25:给定两个长度为N的数组,a[]和b[] 也就是对于每个位置i来说,有a[i]和b[i]两个属性 i a[i] b[i] j a[j] b[j] 现在想为了i,选一个最

    2023-04-25:给定两个长度为N的数组,a[]和b[] 也就是对于每个位置i来说,有a[i]和b[i]两个属性 i a[i] b[i] j a[j] b[j] 现在想为了i,选一个最好的j位置, ...

  9. 2020-10-25:go中channel的close流程是什么?

    福哥答案2020-10-25:

  10. How to use the shell command to get the version of Linux Distributions All In One

    How to use the shell command to get the version of Linux Distributions All In One 如何使用 shell 命令获取 Li ...