一 和为 k 的子数组
1.1 题目描述
给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。
示例 1:
输入:nums = [1,1,1], k = 2
输出: 2
解释: 此题 [1,1] 与 [1,1] 为两种不同的情况
示例 2:
输入:nums = [1,2,3], k = 3
输出: 2
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/QTMn0o
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1.2 思路和代码
按照之前的理解,我使用了滑动窗口的算法,给出的两个没有错误。
public class Solution {
public int SubarraySum(int[] nums, int k) {
int res=0;
int i = 0;
int j = 0;
int sum = 0;
for(;j<nums.Length;j++)
{
sum+= nums[j];
while (sum >= k && i<=j)
{
if (sum == k)
{
res++;
}
sum-= nums[i];
i++;
}
}
return res;
}
}
提交错误,因为可能会存在负数,就会出现错误。
所以修改方法,使用前缀和。
public static int SubarraySum(int[] nums, int k)
{
int res = 0;
int preSum=0;
Dictionary<int ,int> map = new Dictionary<int ,int>();
map.Add(0, 1);
for(int i=0;i<nums.Length;i++)
{
preSum = nums[i]+preSum;
if (map.ContainsKey(preSum - k))
{
res += map[preSum-k];
Console.WriteLine(res);
}
map[preSum]=map.GetValueOrDefault(preSum,0)+1;
}
Console.WriteLine("------------");
Console.WriteLine(res);
return res;
}
此代码的思想是可以查看
前缀和差值的最通俗解释 - 和为 k 的子数组 - 力扣(LeetCode)
需要理解的是preSum[j]-preSum[i]=target。表示[i+1, j]是属于子数
二 0 和 1 个数相同的子数组
2.1 题目描述
给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
示例 1:
输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。
示例 2:
输入: nums = [0,1,0]
输出: 2
说明: [0, 1] (或 [1, 0]) 是具有相同数量 0 和 1 的最长连续子数组。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/A1NYOS
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.2 思路以及代码
此题中出现0,前缀和-1,出现1,前缀和+1。
index | 0 | 1 | 2 |
nums | 0 | 1 | 0 |
preSum | -1 | 0 | -1 |
[0,1] | [1,2] |
public static int FindMaxLength(int[] nums)
{
int res = 0;
int count = 0;
Dictionary<int ,int> directory=new Dictionary<int,int>();
directory.Add(0, -1);
for (int i = 0; i < nums.Length;i++)
{
if(nums[i]==1)
{
count++;
}
else
{
count--;
}
if (directory.ContainsKey(count))
{
res = Math.Max(res, i - directory[count]);
}
else
{
directory.Add(count, i);
}
}
Console.WriteLine(res);
return res;
}