Problem statement:
问题陈述:
Find sum of all subarray sums out of an array.
查找数组中所有子数组总和的和。
Example:
例:
Input array:
[1, 2, 3, 4]
Output:
50
Solution:
解:
Of course, there exists an easy solution where we can use three for loops with time complexity (O (n3)). The outer loop and intermediate loop are to iterate through all subarrays and the innermost one is to compute the sum. But here, we are not going to discuss this simple brute-force solution. Rather we will discuss an efficient way to minimize the time complexity.
当然,存在一个简单的解决方案,其中我们可以使用三个具有时间复杂度(O(n3))的 for循环。 外循环和中间循环将遍历所有子数组,而最内层将计算总和。 但是在这里,我们将不讨论这种简单的暴力解决方案。 相反,我们将讨论一种最小化时间复杂度的有效方法。
Let's look at an example first,
我们先来看一个例子
Array = [1, 2, 3, 4]
Sub-arrays are
[1] =1
[2] =2
[3] =3
[4] =4
[1, 2] =1+2=3
[2, 3] =2+3= 5
[3, 4] =3+4 =7
[1, 2, 3] = 1+2+3= 6
[2, 3, 4] = 2+3+4= 9
[1, 2, 3, 4] = 1+2+3+4 = 10
Total sum= 50
Let's concentrate on finding appearance on each element while calculating the total sum
让我们集中精力在计算总和的同时找到每个元素的外观
If we notice carefully, we can find that we have calculated
如果我们仔细地注意到,我们可以发现我们已经计算出
Sum of
的总和
4 1's = 4*1 = 4
6 2's = 6*2 = 12
6 3's = 6*3 = 18
4 4's = 4*4 = 16
Which is 50
So, if we can come up with an algorithm to find occurrences of each element for an n-length array, then we can compute the total sum in O(n). WE don't even need to compute subarray sums specifically & separately.
因此,如果我们可以提出一种算法来查找n长度数组中每个元素的出现,则可以计算O(n)中的总和。 我们甚至不需要专门和单独计算子数组总和。
So, is there any such algorithm? There is.
那么,有没有这样的算法? 有。
A sub-array is a group of contagious elements
子数组是一组传染性元素
Now,
现在,
An element is a subarray can be the first element of the subarray.
元素是子数组,可以是子数组的第一个元素。
It can be an intermediate or end element of a sub-array starting for any previous element in the array.
它可以是子数组的中间或结尾元素,从该数组中的任何先前元素开始。
So, there is two option.
因此,有两种选择。
Now consider option 1.
现在考虑选项1。
Say an element is at index i of an n-length array
假设元素在n长度数组的索引i处
Then, how many sub-arrays are there which start from the particular element(arr[i])?
那么,从特定元素( arr [i] )开始有多少个子数组?
Answer is (n-i), of course
答案是(ni)当然
As the subarrays of these type are:
由于这些类型的子数组是:
[arr[i] ] //arr be the array name
[arr[i], arr[i+1]]
[arr[i], arr[i+1], arr[i+2] ]
...
...
[arr[i], arr[i+1], arr[i+2], ..., arr[n-1]] // arr[n-1] is the last element
So for option1 there is (n-i) occurences of the arr[i] already
Now consider option2,
现在考虑选项2,
There are i elements preceding the arr[i] (0-indexed, i-index element is actually (i+1)th).
在arr [i]之前有i个元素(索引为0的 i- index元素实际上是第(i + 1) 个 )。
Now, arr[i] may be part of subarrays starting with any of this i (preceded) elements or may not be.
现在, arr [i]可以是以任何i个 (开头)元素开头的子数组的一部分,也可以不是。
Like, for array
[1, 2, 3, 4]
Say i=2
arr[i]=3
像,对于数组
[1、2、3、4]
说我= 2
arr [i] = 3
arr[i] is part of sub-array [1,2,3] but not part of [1] or [1, 2] (both starting from 1 which is part of preceded elements).
arr [i]是子数组[1,2,3]的一部分,但不是[1]或[1,2]的一部分(都从1开始,后者是前面元素的一部分)。
Now the question is of how many subarrays of any preceded element, arr[i] is part of.
现在的问题是,任何前置元素arr [i]包含多少个子数组。
Answer is (n-i) as subarray containing arr[i](starting from any preced element) is similar to the number of subarray starting from arr[i].
答案是(ni),因为包含arr [i](从任何前置元素开始)的子数组与从arr [i]开始的子数组的数量相似。
Total number of occurrences for Option2 is then: i(n-i)
那么,选项2的出现总数为: i(ni)
So, total occurrences of i-index element (arr[i]) =(n-i) + i*(n-i) =(i+1)*(n-i)
因此,i索引元素(arr [i])的总出现次数=(ni)+ i *(ni)=(i + 1)*(ni)
So, total sum can be calculated:
因此,可以计算出总和:
for i=1: n
sum+= arr[i]* (i+1) * (n-i)
Time complexity: O(n)
时间复杂度:O(n)
C ++实现查找数组的所有子数组 (C++ implementation to find all subarray Sum of an array)
#include <bits/stdc++.h>
using namespace std;
#define MAX 1000000007
long long int subarraysum(vector<int> arr, int n)
{
long long int sum = 0;
long long int pro;
//calculation of the formula derived
//arr[i]*(i+1)*(n-i)
for (int i = 0; i < n; i++) {
pro = ((arr[i] % MAX) * (i + 1) % MAX) % MAX;
pro = ((pro % MAX) * ((n - i) % MAX)) % MAX;
sum = ((sum % MAX) + (pro % MAX)) % MAX;
}
return sum;
}
int main()
{
int n, item;
cout << "enter array length\n";
cin >> n;
vector<int> arr;
cout << "enter elements\n";
for (int j = 0; j < n; j++) {
cin >> item;
arr.push_back(item);
}
cout << "Total subarray sum=> " << subarraysum(arr, n) << endl;
return 0;
}
Output
输出量
enter array length
4
enter elements
1 2 3 4
Total subarray sum=> 50
翻译自: https://www.includehelp.com/icp/all-subarray-sum-of-an-array.aspx
本文讨论了一种解决如何在O(n)时间复杂度内计算数组所有子数组总和的方法,避免了使用三重循环的简单暴力求解。通过分析每个元素在子数组中的出现情况,分为两种情况考虑:元素作为子数组起点和作为其他子数组的一部分。通过计算每种情况下的子数组数量,得出总和的公式,并提供了C++的实现。

1112

被折叠的 条评论
为什么被折叠?



