724. 寻找数组的中心下标
-
解题思路
枚举数组中每个元素,计算左边和右边是否相等,相等则返回下标。 -
代码
int pivotIndex(vector<int>& nums) { int len = nums.size(); //1 int sum[len]; for(int i = 0;i<len;++i){ sum[i] = nums[i]; if(i){ sum[i] += sum[i-1]; } } //2 if(sum[len-1]-sum[0] == 0) return 0; //3 for(int j = 1;j<len;++j){ if(sum[j-1]==sum[len-1]-sum[j]) return j; } return -1; }
第一部分,先用一个数组把当前元素的前缀和保存起来;第二部分处理特殊情况->当元素下标为零的时候;第三部分是处理下标为一以后的元素,如果有则直接返回。
- 总结学习
前缀和数组来保存原数组中对应元素的前缀和
1588. 所有奇数长度子数组的和
- 暴力解法
class Solution {
public:
int sumOddLengthSubarrays(vector<int>& arr) {
int len = arr.size();
int i = 1;
int temp = 0;
int sum = 0;
while(i<=len){
for(int j = 0; j <= len-i; ++j){
for(int k = j; k < j+i; ++k){
temp += arr[k];
}
}
sum += temp;
temp = 0;
i = i+2;
}
return sum;
}
};
- 根据统计学理论,元素 i 左边子数组长度的可能情况和右边子数组长的的可能情况,因为是奇数子数组,所以左右奇偶性应该相同,相乘相加后就是元素 i 出现的次数。
int sumOddLengthSubarrays(vector<int>& arr) {
int len = arr.size();
int sum = 0;
int left,right;
int left_even,left_add,right_even,right_add;
for(int i = 0; i < len; ++i){
left = i + 1;
right = len - i;
left_even = (left+1)/2;
left_add = left/2;
right_even = (right+1)/2;
right_add = right/2;
sum += arr[i]*(left_add*right_add + left_even*right_even);
}
return sum;
}
303. 区域和检索 - 数组不可变
class NumArray {
public:
vector<int> sum;
NumArray(vector<int>& nums) {
int len = nums.size();
sum.reszie(len+1,0);
sum[1] = nums[1];
for(int i = 1;i<len;++i){
sum[i] = sum[i-1] + nums[i];
}
}
int sumRange(int left, int right) {
}
};
```
- 总结
前缀和数组有两种:
一种是前缀和数组表示原数组中当前元素前的元素和 需要比原数组长度加1。303. 区域和检索 - 数组不可变就是这种情况
另一种是前缀和数组表示原数组中包含当前元素的元素和。 724. 寻找数组的中心下标 题解就是这种情况