Leetcode 560 和为k的连续子数组
给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
示例 1 :
输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :
数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。
思路1:常规双for遍历,和为k就++
int subarraySum(int* nums, int numsSize, int k){
int * preSum =(int *)malloc(sizeof(int)*(numsSize+1));
int count = 0;
preSum[0] = 0;
for(int i=1;i<numsSize+1;i++){
preSum[i] = preSum[i-1] + nums[i-1];
}
for(int i=0;i<numsSize;i++){
for(int j=i+1;j<numsSize+1;j++){
if(preSum[j]-preSum[i] == k)
count++;
}
}
free(preSum);
preSum = NULL;
return count;
}
思路2:刚刚做过区间和的个数,https://blog.csdn.net/qq_40405527/article/details/108085048这题就是特例版本啊,当区间为[k,k]则是本题,所以稍加修改即可(nums[i] 中 由于无需求i,j的区间位置,在固定i的情况下,将右边进行排序,找到符合的最大值和最小值,相间即当前轮的和为k的个数)
void MergeSort(int *nums,int start,int mid,int end,int equ,int* count){
int i = start;
int j = mid+1;
int k = 0;
int len = end-start+1;
int *temp = (int *)malloc(sizeof(int)*len);
while(i <= mid && j <= end){
if(nums[i] < nums[j]){
temp[k++] = nums[i++];
}
else{
temp[k++] = nums[j++];
}
}
if(i == mid+1){
while(j <= end){
temp[k++] = nums[j++];
}
}
if(j == end+1){
while(i <= mid){
temp[k++] = nums[i++];
}
}
i=start;
int equlower = mid + 1;
int equupper = mid + 1;
while(i <= mid){
while(equlower <= end && nums[equlower]-nums[i]<equ){
equlower++;
}
while(equupper <= end && nums[equupper]-nums[i]<=equ){
equupper++;
}
*count += equupper - equlower;
i++;
}
for(i=start,j=0;j<len;i++,j++){
nums[i] = temp[j];
}
free(temp);
temp = NULL;
}
void Merge(int *nums,int start,int end,int k,int *count){
if(start < end){
int mid = (start + end)/2;
Merge(nums,start,mid,k,count);
Merge(nums,mid+1,end,k,count);
MergeSort(nums,start,mid,end,k,count);
}
}
int subarraySum(int* nums, int numsSize, int k){
int * preSum =(int *)malloc(sizeof(int)*(numsSize+1));
int count = 0;
preSum[0] = 0;
for(int i=1;i<numsSize+1;i++){
preSum[i] = preSum[i-1] + nums[i-1];
}
Merge(preSum,0,numsSize,k,&count);
free(preSum);
preSum = NULL;
return count;
}