/*
1.给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空),使得剩余元素的 和 能被 p 整除。 不允许 将整个数组都移除。
2.请你返回你需要移除的最短子数组的长度,如果无法满足题目要求,返回 -1 。子数组 定义为原数组中连续的一组元素*/
class Solution {
public int minSubarray(int[] nums, int p) {
int n = nums.length;
int m = 0;
for (int x : nums) {
m = (m + x) % p; //得到所需的元素和
}
if(m == 0) {
return 0;
}
int sum = 0, res = n;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
for (int i = 0; i < n; i ++) {
sum = (sum + nums[i]) % p; //得到的和
int q = (sum - m + p) % p; //
if(map.containsKey(q)) {
res = Math.min(res, i - map.get(q));
}
map.put(sum, i);
}
return res == n ? -1 : res; //
}
}
/*给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。 */
class Solution {
public int subarraysDivByK(int[] nums, int k) {
HashMap<Integer, Integer> record = new HashMap<Integer, Integer>();
record.put(0,1);
int sum = 0, ans = 0;
for (int num : nums) {
sum += num;
int m = (sum % k + k) % k;//得到满足的数组
int same = record.getOrDefault(m, 0);//统计符合的数组的子数组...
ans += same;//计数所得符合的数组
record.put(m, same + 1);
}
return ans;
}
}
3.剑指 Offer II 011. 0 和 1 个数相同的子数组
/*给定一个二进制数组 nums,找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度*/
class Solution {
public int findMaxLength(int[] nums) {
int n = nums.length, sum = 0, res = 0;
HashMap<Integer, Integer> map = new HashMap<>();
//和为0的时候下标为-1
map.put(0, -1);
for(int i = 0; i < n; i++) {
if(nums[i] == 0) {
sum -= 1;
}else {
sum += 1;
}
if(map.containsKey(sum)) {
res = Math.max(res, i - map.get(sum));
}else {
map.put(sum, i);
}
}
return res;
}
}
/*给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度*/
class Solution {
public int findMaxLength(int[] nums) {
int res = 0, sum = 0;
for (int i = 0; i < nums.length; i++) {
if(nums[i] == 0) {
nums[i] = -1;//诺不存在的就返回-1
}
}
HashMap <Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
if(sum == 0 && i > res) {//找到的含有连续相同的0,1子数组
res = i + 1;
}
if(map.containsKey(sum)) {
res = Math.max(i - map.get(sum), res);//返回连续相同0,1子数组的长度最大值
}else {
map.put(sum, i);
}
}
return res;
}
}