前缀和简单题
int *leftRightDifference(int *nums, int numsSize, int *returnSize) {
int *res = (int *) malloc(sizeof(int) * numsSize);
*returnSize = numsSize;
int leftSum = 0, rightSum = 0;
// 求和
for (int i = 0; i < numsSize; ++i) rightSum += nums[i];
for (int i = 0; i < numsSize; ++i) {
// 计算后缀和
rightSum -= nums[i];
res[i] = abs(leftSum - rightSum);
// 计算下次用的前缀和
leftSum += nums[i];
}
return res;
}
int sumOddLengthSubarrays(int *arr, int arrSize) {
int res = 0;
int *sum = (int *) calloc(arrSize + 1, sizeof(int));
for (int i = 1; i <= arrSize; ++i)
sum[i] += sum[i - 1] + arr[i - 1];
int gap = 1;
// i = 0, sum[i+gap] - sum[i] gap=1
// i = 0, sum[i+gap] - sum[i] gap=3
// i = 0, sum[i+gap] - sum[i] gap=5
while (gap <= arrSize) {
for (int i = gap; i <= arrSize; ++i) {
res += sum[i] - sum[i - gap];
}
gap += 2;
}
return res;
}
// todo
int sumOddLengthSubarrays(int *arr, int arrSize) {
int res = 0;
for (int i = 0; i < arrSize; ++i) {
int left = i + 1, right = arrSize - i;
int leftEven = (left + 1) >> 1, rightEven = (right + 1) >> 1;
int leftOdd = left >> 1, rightOdd = right >> 1;
res += (leftEven * rightEven + leftOdd * rightOdd) * arr[i];
}
return res;
}
int largestAltitude(int *gain, int gainSize) {
int sum = 0;
int max = 0;
for (int i = 0; i < gainSize; ++i) {
sum += gain[i];
if (max < sum) max = sum;
}
return max;
}
int pivotInteger(int n) {
int total = (1 + n) * n >> 1;
int prefixSum = total;
// 倒着找的更快
for (int i = n; i >= 1; i--) {
// 检查前i个数之和是否等于后(n-i+1)个数之和
if (prefixSum == ((i + n) * (n - i + 1) >> 1)) return i;
prefixSum -= i;
}
return -1;
}
// 数学计算
int pivotInteger(int n) {
int total = n * (n + 1) / 2;
int x = sqrt(total);
return x * x == total ? x : -1;
}
// 打表
int pivotInteger(int n) {
switch (n) {
case 1:
return 1;
case 8:
return 6;
case 49:
return 35;
case 288:
return 204;
default:
return -1;
}
}
typedef struct {
int *sum;
} NumArray;
NumArray *numArrayCreate(int *nums, int numsSize) {
NumArray *numArray = (NumArray *) malloc(sizeof(NumArray));
numArray->sum = (int *) calloc(numsSize + 1, sizeof(int));
// 计算前缀和
for (int i = 1; i <= numsSize; ++i) {
numArray->sum[i] += numArray->sum[i - 1] + nums[i - 1];
}
return numArray;
}
int numArraySumRange(NumArray *obj, int left, int right) {
return obj->sum[right + 1] - obj->sum[left];
}
void numArrayFree(NumArray *obj) {
if (obj != NULL) {
free(obj);
obj = NULL;
}
}
int *runningSum(int *nums, int numsSize, int *returnSize) {
int *res = (int *) calloc(numsSize, sizeof(int));
*returnSize = numsSize;
res[0] = nums[0];
for (int i = 1; i < numsSize; ++i)
res[i] += res[i - 1] + nums[i];
return res;
}
// todo
int minStartValue(int *nums, int numsSize) {
int prefixSum = 0;
int min = 101;
for (int i = 0; i < numsSize; ++i) {
prefixSum += nums[i];
if (prefixSum < min) min = prefixSum;
}
if (min > 0) return 1;
return 1 - min;
}
int pivotIndex(int *nums, int numsSize) {
int total = 0;
for (int i = 0; i < numsSize; ++i)
total += nums[i];
int prefixSum = 0;
for (int i = 0; i < numsSize; ++i) {
if (prefixSum == total - prefixSum - nums[i])
return i;
prefixSum += nums[i];
}
return -1;
}
// todo