560和为K的子数组 (在前面解数组篇)解法三 前缀和+HashMap
974和可被K整除的子数组 难度 中等
前缀和,注意取余的方式。每遍历数组的一个数就计算这个数取余转化后的形式是哪个数(代码中的key),
map.getOrDefault(key,replace_words)其实就相当于map.get(key)的升级版,如果map中含有对应的key,则相当于get(),如果没有则输出replace_words
class Solution {
public int subarraysDivByK(int[] A, int K) {
HashMap<Integer,Integer> map = new HashMap<>();
map.put(0,1); //注意:需要先存第一个,否则会遗漏情况
int presum = 0;
int count = 0;
for (int x : A) { //思考 之前先存入的第一个数,现在又从第一个开始遍历,应该不会冲突?因为是presum(没用到map)从0开始加第一个数,然后判断map里有没有
presum += x; //一个数,记录每次循环时的前缀和,用来计算,不存入数组
//当前 presum 与 K的关系,余数是几,当被除数为负数时取模结果为负数,需要纠正
int key = (presum % K + K) % K; //?思考(presum%k+k)%k ?
//查询哈希表获取之前key也就是余数的次数
if (map.containsKey(key)) {
count += map.get(key); // Map.get()方法返回指定键所映射的值
}
//存入哈希表当前key,也就是余数
map.put(key,map.getOrDefault(key,0)+1); //如果没有值,默认是0。+1是因为存入当前的,不管map之前有没有,这次存都次数+1
}
return count;
}
}
问题 如果存之后,假设次数4次已经算进count里了,4+1=5,后面算出来又是同一个key,count又+5,是不是重复加了??
523.连续的子数组和 难度 中等 ???
key记录?
???
724寻找数组的中心下标 难度 简单
先遍历一遍求出数组的和,然后第二次遍历时,直接进行对比左半部分和右半部分是否相同,如果相同则返回 true,不同则继续遍历。
class Solution {
public int pivotIndex(int[] nums) {
int presum = 0;
//数组的和
for (int x : nums) {
presum += x; //不是前缀和,是整个数组的和
}
int leftsum = 0;
for (int i = 0; i < nums.length; ++i) { //遍历数组
//发现相同情况
if (leftsum == presum - nums[i] - leftsum) { //把-leftsum换成/2应该也行?
return i;
}
leftsum += nums[i]; //左半部分的和,约等于从0开始到当前的前缀和
}
return -1;
}
}
1248寻找优美子数组????
区间问题 考虑前缀和的思想
思路1 ?
上个题目我们是求和为 K 的子数组,这个题目是让我们求 恰好有 k 个奇数数字的连续子数组,这两个题几乎是一样的,上个题中我们将前缀区间的和保存到哈希表中,这个题目我们只需将前缀区间的奇数个数保存到区间内即可,只不过将 sum += x 改成了判断奇偶的语句
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
if (nums.length == 0) {
return 0;
}
HashMap<Integer,Integer> map = new HashMap<>();
//统计奇数个数,相当于我们的 presum
int oddnum = 0;
int count = 0;
map.put(0,1);
for (int x : nums) { //遍历数组
// 统计奇数个数
oddnum += x & 1; //判断奇偶数,奇数返回1,偶数0。奇数count+1
// 发现存在,则 count增加
if (map.containsKey(oddnum - k)) { //(实际奇数数量-k)个奇数
count += map.get(oddnum - k); //??如果当前不是奇数,加上这个新的偶数算一个新区间,所以加一????
}
//存入
map.put(oddnum,map.getOrDefault(oddnum,0)+1);
}
return count;
}
}
思路2 ???
但是也有一点不同,就是我们是统计奇数的个数,数组中的奇数个数肯定不会超过原数组的长度,所以这个题目中我们可以用数组来模拟 HashMap ,用数组的索引来模拟 HashMap 的 key,用值来模拟哈希表的 value。
class Solution {
public int numberOfSubarrays(int[] nums, int k) {
int len = nums.length;
int[] map = new int[len + 1];
map[0] = 1;
int oddnum = 0;
int count = 0;
for (int i = 0; i < len; ++i) {
//如果是奇数则加一,偶数加0,相当于没加
oddnum += nums[i] & 1;
if (oddnum - k >= 0) { ????????
count += map[oddnum-k];
}
map[oddnum]++;
}
return count;
}
}
最近有点难
终于吃饭
幸运值一定+++++++