Given an array arr[], find the average or mean of the prefix array at every index.
Examples:
Input: arr[] = [10, 20, 30, 40, 50]
Output: [10, 15, 20, 25, 30]
Explanation: 10 / 1 = 10, (10 + 20) / 2 = 15, (10 + 20 + 30) / 3 = 20 and so on.
Input: arr[] = [12, 1]
Output: [12, 6]
Explanation: 12 / 1 = 12, (12 + 1) / 2 = 6
Computing Running Sum - O(n) Time
The idea is to compute sum till every point and compute average at every point. The problem with this solution is, it causes overflow even for small values.
Let us understand with an example:
Input: arr[] = 10, 20, 30, 40, 50
Start traversal: Initialize avg = 0
- At 10 -> sum = 10, store 10 / 1 = 10
- At 20 -> sum = 30, store 30 / 2 = 15
- At 30 -> sum = 60, store 60 / 3 = 20
- At 40 -> sum = 100, store 100 / 4 = 25
- At 50 -> sum = 150, store 150 / 5 = 30
All elements processed. Final array = 10, 15, 20, 25, 30
#include <iostream>
using namespace std;
// Prints sum of a stream of numbers
vector<int> prefixSum(vector<int> &arr)
{
int n = arr.size();
// initialize a vector to store the sum values
vector<int> ans(n, 0);
// initialize a variable to store the sum of numbers
int sum = 0;
// iterate through the array
for (int i = 0; i < n; i++)
{
// add the current number to the sum
sum += arr[i];
// store the sum in the vector
ans[i] = sum/(i+1);
}
// return the vector of sum values
return ans;
}
// Driver Code
int main() {
vector<int> arr = {10, 20, 30, 40, 50};
vector<int> res = prefixSum(arr);
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
return 0;
}
import java.util.ArrayList;
import java.util.Arrays;
// Prints sum of a stream of numbers
public class Main {
public static ArrayList<Integer> prefixSum(int[] arr) {
int n = arr.length;
// initialize an ArrayList to store the sum values
ArrayList<Integer> ans = new ArrayList<>(Arrays.asList(new Integer[n]));
// initialize a variable to store the sum of numbers
int sum = 0;
// iterate through the array
for (int i = 0; i < n; i++) {
// add the current number to the sum
sum += arr[i];
// store the sum in the ArrayList
ans.set(i, sum / (i + 1));
}
// return the ArrayList of sum values
return ans;
}
// Driver Code
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
ArrayList<Integer> res = prefixSum(arr);
for (int i = 0; i < res.size(); i++) {
System.out.print(res.get(i) + " ");
}
}
}
def prefixSum(arr):
n = len(arr)
# initialize a list to store the sum values
ans = [0] * n
# initialize a variable to store the sum of numbers
sum = 0
# iterate through the array
for i in range(n):
# add the current number to the sum
sum += arr[i]
# store the sum in the list
ans[i] = sum // (i + 1)
# return the list of sum values
return ans
# Driver Code
arr = [10, 20, 30, 40, 50]
res = prefixSum(arr)
for i in range(len(res)):
print(res[i], end=' ')
using System;
using System.Collections.Generic;
// Prints sum of a stream of numbers
public class Program
{
public static List<int> prefixSum(int[] arr)
{
int n = arr.Length;
// initialize a list to store the sum values
List<int> ans = new List<int>(new int[n]);
// initialize a variable to store the sum of numbers
int sum = 0;
// iterate through the array
for (int i = 0; i < n; i++)
{
// add the current number to the sum
sum += arr[i];
// store the sum in the list
ans[i] = sum / (i + 1);
}
// return the list of sum values
return ans;
}
// Driver Code
public static void Main()
{
int[] arr = { 10, 20, 30, 40, 50 };
List<int> res = prefixSum(arr);
for (int i = 0; i < res.Count; i++)
{
Console.Write(res[i] + " ");
}
}
}
// Prints sum of a stream of numbers
function prefixSum(arr) {
let n = arr.length;
// initialize an array to store the sum values
let ans = new Array(n).fill(0);
// initialize a variable to store the sum of numbers
let sum = 0;
// iterate through the array
for (let i = 0; i < n; i++) {
// add the current number to the sum
sum += arr[i];
// store the sum in the array
ans[i] = Math.floor(sum / (i + 1));
}
// return the array of sum values
return ans;
}
// Driver Code
let arr = [10, 20, 30, 40, 50];
let res = prefixSum(arr);
for (let i = 0; i < res.length; i++) {
console.log(res[i] + ' ');
}
Output
10 15 20 25 30
Running Average to Avoid Overflow - O(n) Time
The idea is to avoid overflow by avoiding sum computation.
The idea is to maintain a variable
avgto store the running sum and traverse the array from left to right. At each indexi, we add the current element toavg, then compute the average asavg / (i + 1)and store it in the result array.
Let us understand with an example:
Input: arr[] = [1, 3, 4, 2, 6, 5, 8, 7]
Start traversal: Initialize avg = 0
- At 1 -> avg = 1
- At 3 -> avg = 1 + (3 - 1)/2 = 2
- At 4 -> avg = 2 + (4 - 2)/3 = 2.67
- At 2 -> avg = 2.67 + (2 - 2.67)/4 = 2.5
- At 6 -> avg = 3.2
- At 5 -> avg = 3.5
- At 8 -> avg ≈ 4.14
- At 7 -> avg = 4.5
#include <iostream>
#include <vector>
using namespace std;
vector<int> prefixAvg(vector<int> &arr)
{
vector<int> res;
long double avg = 0;
int n = arr.size();
for (int i = 0; i < n; i++)
{
// Update avg
avg += (arr[i] - avg) / (i + 1);
res.push_back((int)avg);
}
return res;
}
// Driver Code
int main()
{
vector<int> arr = {10, 20, 30, 40, 50};
vector<int> res = prefixAvg(arr);
for (int i = 0; i < res.size(); i++)
{
cout << res[i] << " ";
}
return 0;
}
import java.util.ArrayList;
import java.util.List;
public class Main {
public static List<Integer> prefixAvg(int[] arr) {
List<Integer> res = new ArrayList<>();
double avg = 0;
int n = arr.length;
for (int i = 0; i < n; i++) {
// Update avg
avg += (arr[i] - avg) / (i + 1);
res.add((int)avg);
}
return res;
}
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
List<Integer> res = prefixAvg(arr);
for (int i = 0; i < res.size(); i++) {
System.out.print(res.get(i) + " ");
}
}
}
def prefixAvg(arr):
res = []
avg = 0
n = len(arr)
for i in range(n):
# Update avg
avg += (arr[i] - avg) / (i + 1)
res.append(int(avg))
return res
# Driver Code
arr = [10, 20, 30, 40, 50]
res = prefixAvg(arr)
for i in range(len(res)):
print(res[i], end=' ')
using System;
using System.Collections.Generic;
class Program
{
static List<int> prefixAvg(List<int> arr)
{
List<int> res = new List<int>();
double avg = 0;
int n = arr.Count;
for (int i = 0; i < n; i++)
{
// Update avg
avg += (arr[i] - avg) / (i + 1);
res.Add((int)avg);
}
return res;
}
// Driver Code
static void Main()
{
List<int> arr = new List<int> {10, 20, 30, 40, 50};
List<int> res = prefixAvg(arr);
for (int i = 0; i < res.Count; i++)
{
Console.Write(res[i] + " ");
}
}
}
function prefixAvg(arr) {
let res = [];
let avg = 0;
let n = arr.length;
for (let i = 0; i < n; i++) {
// Update avg
avg += (arr[i] - avg) / (i + 1);
res.push(Math.floor(avg));
}
return res;
}
// Driver Code
let arr = [10, 20, 30, 40, 50];
let res = prefixAvg(arr);
for (let i = 0; i < res.length; i++) {
console.log(res[i] + " ");
}
Output
10 15 20 25 30
Time Complexity: O(n)
Auxiliary Space: O(n)