习题
1480. 一维数组的动态和
简单的前缀和
int* runningSum(int* nums, int numsSize, int* returnSize){int * ret = (int *)malloc(sizeof(int) * numsSize);ret[0] = nums[0];for(int i = 1; i < numsSize; ++i) {ret[i] = ret[i - 1] + nums[i];}*returnSize = numsSize;return ret;
}
724. 寻找数组的中心下标
#define maxn 10001
int sum[maxn]; //定义前缀和数组int pivotIndex(int* nums, int numsSize) {sum[0] = nums[0];for(int i = 1; i < numsSize; ++i) {sum[i] = sum[i - 1] + nums[i];}if(sum[numsSize - 1] - sum[0] == 0) return 0;int ans = -1;for(int i = 1; i < numsSize; ++i) {if(sum[i - 1] == sum[numsSize - 1] - sum[i]) {ans = i;break;}}return ans;
}
通过定义左右的和,并依次做变换如果相等则得到结果。
要找的是最左边的,所以先把右边加满。
左边+1,右边-1,如果相等则返回。
int pivotIndex(int* nums, int numsSize) {int left = 0;int right = 0;for(int i = 0; i < numsSize; ++i) {right += nums[i];}for(int i = 0; i < numsSize; ++i) {right -= nums[i];if(right == left) return i;left += nums[i];}return -1;
}
1310. 子数组异或查询
#define MAXX 30001
int xor[MAXX];int* xorQueries(int* arr, int arrSize, int** queries, int queriesSize, int* queriesColSize, int* returnSize) {int * ret = (int *)malloc(sizeof(int) * queriesSize);*returnSize = queriesSize;xor[0] = arr[0];for(int i = 1; i < arrSize; ++i) {xor[i] = xor[i - 1] ^ arr[i];}int ans = 0;for(int i = 0; i < queriesSize; ++i) {//获取queries的左右值int l = queries[i][0];int r = queries[i][1];if(l == 0) {ans = xor[r]; //如果从头开始则直接返回r的值}else {ans = xor[r] ^ xor[l - 1]; //否则需要减去前面截取的部分}ret[i] = ans;}return ret;
}
974. 和可被 K 整除的子数组
#define MAX 30001
int sum[MAX];
int hash[MAX];int subarraysDivByK(int* nums, int numsSize, int k) {int ans = 0;sum[0] = nums[0] % k;if(sum[0] < 0) sum[0] += k;memset(hash, 0 ,sizeof(hash));for(int i = 1; i < numsSize; ++i) {sum[i] = (sum[i - 1] + nums[i]) % k;if(sum[i] < 0) sum[i] += k;}hash[0] = 1;for(int j = 0; j <numsSize; ++j) {ans += hash[sum[j]];hash[ sum[j] ] ++;}return ans;
}
2485. 找出中枢整数
这一题是简单题,和前面套路一样,算出前缀和之后进行判断就可以了。
int sum[1001];int pivotInteger(int n) {if(n == 1) return 1;sum[1] = 1;for(int i = 2; i <= n; ++i) {sum[i] = sum[i - 1] + i;}for(int i = 1; i <= n; ++i) {if(sum[i] == sum[n] - sum[i - 1]) {return i;}}return -1;
}
1588. 所有奇数长度子数组的和
这道题如何将每个奇数组找出来想了一段时间,思路能想出来就是代码费了点时间。
int sum[110];int sumOddLengthSubarrays(int* arr, int arrSize){// 前缀和sum[0] = arr[0];int ret = arr[0];for(int i = 1; i < arrSize; ++i) {sum[i] = sum[i - 1] + arr[i];ret += arr[i];}int step = 2;// 外层设置步长while(step < arrSize) {int sub = step + 1;// 内层根据题目要求加for(int i = step; i < arrSize; i++) {if(i - sub < 0) {ret += sum[i];}else {ret += sum[i] - sum[i - sub];}}step += 2;}return ret;
}
930. 和相同的二元子数组
int hash[60001];
int sum[30001];int numSubarraysWithSum(int* nums, int numsSize, int goal){memset(hash, 0, sizeof(hash));++hash[ goal ];sum[0] = nums[0];for(int i = 1; i < numsSize; ++i) {sum[i] = sum[i - 1] + nums[i];}int ans = 0;for(int i = 0; i < numsSize; ++i) {ans += hash[ sum[i] ];++hash[ sum[i] + goal ];}return ans;
}