Given an array of positive integers arr, please calculate the sum of all possible odd-length sub-arrays.
The sub-array is defined as a continuous sub-sequence in the original array. Please return the sum of all odd-length subarrays in arr.
Example 1:
Input: arr = [1,4,2,5,3]
Output: 58
Explanation: All odd-length sub-arrays and their sum are:
The sub-array of length 1 has [1],[4],[2],[5],[3] and the result of the addition is 15
The sub-array of length 3 has [1,4,2],[4,2,5],[2,5,3], the result of the addition is 7+11+10=28
The sub-array of length 5 has [1,4,2,5,3], the result of the addition is 15
We sum all the values to get 15+28+15 = 58
Example 2:
Input: arr = [1,2]
Output: 3
Explanation: There are only 2 sub-arrays of length 1, [1] and [2]. Their sum is 3.
Algorithm 1: traverse and add according to the requirements of the topic
int sumOddLengthSubarrays(int* arr, int arrSize) //效率较低
{
int sum = 0;
for(int i=1;i<=arrSize;i+=2)//遍历所有奇数的子长度,如1,3,5,...,2n+1
{
for(int j=0;j<arrSize-i+1;j++)//每一组子数组
{
for(int k=0;k<i;k++)//把子数组的所有数字相加
{
sum += arr[j+k];
}
}
}
return sum;
}
Algorithm 2: Calculate the number of occurrences of each number, and then add them
to gradually calculate the sum of the sub-arrays according to the meaning of the question. It is found that each number appears multiple times and is calculated multiple times, so I think about whether it can directly calculate the number of occurrences of each number. The idea is as follows:
1. Take any element with the index i (i+1) of the array
2. There can be 0~i elements on the left, i+1 schemes in total, among which (i+1)/2 are odd numbers, and i/2+1 are even numbers.
3. On the right, you can take 0~(ni-1) elements, there are ni kinds of schemes, (ni)/2 are odd numbers, and (n-i+1)/2 are even numbers
4. The composite sub-array must meet the conditions: left + itself + right = odd number, so left odd -> right odd, left even -> right even
5. So the number of occurrences of arr[i] is lOdd X rOdd + lEven X rEven, which is left odd X right odd + left even X right even
int sumOddLengthSubarrays(int* arr, int arrSize)
{
int res = 0;
int lEven,lOdd,rEven,rOdd;//左偶数,左奇数,右偶数,右奇数
for(int i=0;i<arrSize;i++)
{
lOdd = (i+1)/2;
lEven = i/2 + 1;
rOdd = (arrSize-i)/2;
rEven = (arrSize-i+1)/2;
res += (lOdd*rOdd + lEven*rEven) * arr[i];
}
return res;
}