为每个 Array 元素查找每侧 K 个相邻元素的平均值
给定一个包含N个数字的循环数组arr[]和一个整数K。任务是打印每个元素的2K+1 个数字的平均值(K 从左,K 从右,以及元素自身)。
例子:
Input: arr []= { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, K = 3
Output: {4.85714, 4.57143, 4.28571, 4.0, 5.0, 6.0, 5.71429, 5.42857, 5.14286}
Explanation: For each value the averages are:
for 1 – right part:9, left part:24 & result:4.85714
for 2 – right part:12, left part:18 & result:4.57143
for 3 – right part:15, left part:12 & result:4.28571
for 4 – right part:18, left part:6 & result:4
for 5 – right part:21, left part:9 & result:5
for 6 – right part:24, left part:12 & result:6
for 7 – right part:18, left part:15 & result:5.71429
for 8 – right part:12, left part:18 & result:5.42857
for 9 – right part:6, left part:21 & result:5.14286
Input: arr[] = {2, 2, 2, 2, 2}, K = 3
Output: {2, 2, 2, 2, 2}
朴素方法:解决问题的最简单方法是遍历数组中每个元素所需的元素数量。请按照以下步骤操作:
- 遍历数组并对每个元素执行以下操作:
- 遍历下 K 个和前 K 个元素并计算这些元素的平均值。
- 打印每个元素的答案。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to calculate average
void average(int arr[], int N, int K)
{
// Iterate over all elements
for (int i = 0; i < N; i++) {
int leftSum = 0;
int rightSum = 0;
// find the right sum
for (int j = 1; j <= K; j++) {
rightSum += arr[(i + j) % N];
}
// Find the leftSum
for (int j = 1; j <= K; j++) {
leftSum += arr[(i - j < 0
? i - j + N
: i - j)
% N];
}
// Print mean for each element
cout << ((leftSum + rightSum + arr[i])
* 1.0)
/ (2 * K + 1)
<< " ";
}
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = sizeof(arr) / sizeof(int);
average(arr, N, K);
return 0;
}
Java
// Java code to implement the above approach
import java.util.*;
public class GFG{
// Function to calculate average
static void average(int[] arr, int N, int K)
{
// Iterate over all elements
for(int i = 0; i < N; i++)
{
int leftSum = 0;
int rightSum = 0;
// Find the right sum
for(int j = 1; j <= K; j++)
{
rightSum += arr[(i + j) % N];
}
// Find the leftSum
for(int j = 1; j <= K; j++)
{
leftSum += arr[(i - j < 0 ? i - j + N : i - j) % N];
}
// Print mean for each element
System.out.print( ((leftSum + rightSum + arr[i]) * 1.0) /
(2 * K + 1) + " ");
}
}
// Driver code
public static void main(String args[])
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = arr.length;
average(arr, N, K);
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python code for the above approach
# Function to calculate average
def average(arr, N, K):
# Iterate over all elements
for i in range(N):
leftSum = 0
rightSum = 0
# find the right sum
for j in range(1, K + 1):
rightSum += arr[(i + j) % N]
# Find the leftSum
for j in range(1, K + 1):
leftSum += arr[((i - j + N) if (i - j < 0) else (i - j)) % N]
# Print mean for each element
print(round(((leftSum + rightSum + arr[i]) * 1.0) / (2 * K + 1), 5), end=" ")
# Driver code
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
K = 3
N = len(arr)
average(arr, N, K)
# This code is contributed by Saurabh Jaiswal
C#
// C# code to implement the above approach
using System;
class GFG{
// Function to calculate average
static void average(int[] arr, int N, int K)
{
// Iterate over all elements
for(int i = 0; i < N; i++)
{
int leftSum = 0;
int rightSum = 0;
// Find the right sum
for(int j = 1; j <= K; j++)
{
rightSum += arr[(i + j) % N];
}
// Find the leftSum
for(int j = 1; j <= K; j++)
{
leftSum += arr[(i - j < 0 ? i - j + N : i - j) % N];
}
// Print mean for each element
Console.Write( ((leftSum + rightSum + arr[i]) * 1.0) /
(2 * K + 1) + " ");
}
}
// Driver code
public static void Main()
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = arr.Length;
average(arr, N, K);
}
}
// This code is contributed by ukasp
Javascript
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to calculate the average
void average(int arr[], int N, int K)
{
int presum[N];
presum[0] = arr[0];
for (int i = 1; i < N; i++) {
presum[i] = presum[i - 1] + arr[i];
}
for (int i = 0; i < N; i++) {
// Right part
int rightSum = 0;
// When all k-elements are
// in right
if (i + K < N)
rightSum = presum[i + K]
- presum[i];
else {
int eleInRight = N - i - 1;
// When some are in right and
// some needs circular traversal
if (eleInRight > 0) {
rightSum = presum[N - 1]
- presum[i]
+ presum[K - eleInRight - 1];
}
else {
rightSum = presum[K - eleInRight - 1];
}
}
// Left part
int leftSum = 0;
// When more than k-elements
// are in left
if (i - K > 0)
leftSum = presum[i - 1]
- presum[i - K - 1];
// When exact k-elements are in left
else if (i - K == 0) {
leftSum = presum[i - 1];
}
// When some are in left some
// needs circular traversal
else {
int eleInLeft = i;
if (eleInLeft > 0) {
leftSum = presum[i - 1]
+ presum[N - 1]
- presum[N - 1 - (K - eleInLeft)];
}
else {
leftSum = presum[N - 1]
- presum[N - 1 - K];
}
}
cout << ((arr[i] + leftSum + rightSum)
* 1.0)
/ (2 * K + 1)
<< " ";
}
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = sizeof(arr) / sizeof(int);
average(arr, N, K);
return 0;
}
Java
// Java code to implement the above approach
import java.util.*;
public class GFG
{
// Function to calculate the average
static void average(int arr[], int N, int K)
{
int presum[] = new int[N];
presum[0] = arr[0];
for (int i = 1; i < N; i++) {
presum[i] = presum[i - 1] + arr[i];
}
for (int i = 0; i < N; i++) {
// Right part
int rightSum = 0;
// When all k-elements are
// in right
if (i + K < N)
rightSum = presum[i + K]
- presum[i];
else {
int eleInRight = N - i - 1;
// When some are in right and
// some needs circular traversal
if (eleInRight > 0) {
rightSum = presum[N - 1]
- presum[i]
+ presum[K - eleInRight - 1];
}
else {
rightSum = presum[K - eleInRight - 1];
}
}
// Left part
int leftSum = 0;
// When more than k-elements
// are in left
if (i - K > 0)
leftSum = presum[i - 1]
- presum[i - K - 1];
// When exact k-elements are in left
else if (i - K == 0) {
leftSum = presum[i - 1];
}
// When some are in left some
// needs circular traversal
else {
int eleInLeft = i;
if (eleInLeft > 0) {
leftSum = presum[i - 1]
+ presum[N - 1]
- presum[N - 1 - (K - eleInLeft)];
}
else {
leftSum = presum[N - 1]
- presum[N - 1 - K];
}
}
System.out.print(((arr[i] + leftSum + rightSum)
* 1.0)
/ (2 * K + 1)
+ " ");
}
}
// Driver code
public static void main(String args[])
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = arr.length;
average(arr, N, K);
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python code to implement the above approach
# Function to calculate the average
def average(arr, N, K):
presum = [0]*N
presum[0] = arr[0]
for i in range(1,N):
presum[i] = presum[i - 1] + arr[i]
for i in range(0,N):
# Right part
rightSum = 0
# When all k-elements are
# in right
if (i + K < N):
rightSum = presum[i + K] - presum[i]
else:
eleInRight = N - i - 1
# When some are in right and
# some needs circular traversal
if (eleInRight > 0):
rightSum = presum[N - 1] - presum[i] + presum[K - eleInRight - 1]
else:
rightSum = presum[K - eleInRight - 1]
# Left part
leftSum = 0
# When more than k-elements
# are in left
if (i - K > 0):
leftSum = presum[i - 1] - presum[i - K - 1]
# When exact k-elements are in left
elif (i - K == 0):
leftSum = presum[i - 1]
# When some are in left some
# needs circular traversal
else:
eleInLeft = i
if (eleInLeft > 0):
leftSum = presum[i - 1] + presum[N - 1] - presum[N - 1 - (K - eleInLeft)]
else:
leftSum = presum[N - 1] - presum[N - 1 - K]
print("{:.5f}".format(((arr[i] + leftSum + rightSum) * 1.0) / (2 * K + 1)),end = " ")
# Driver code
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
K = 3
N = len(arr)
average(arr, N, K)
# This code is contributed by Shubham Singh
C#
// C# code to implement the above approach
using System;
public class GFG{
// Function to calculate the average
static void average(int[] arr, int N, int K)
{
int[] presum = new int[N];
presum[0] = arr[0];
for (int i = 1; i < N; i++) {
presum[i] = presum[i - 1] + arr[i];
}
for (int i = 0; i < N; i++) {
// Right part
int rightSum = 0;
// When all k-elements are
// in right
if (i + K < N)
rightSum = presum[i + K]
- presum[i];
else {
int eleInRight = N - i - 1;
// When some are in right and
// some needs circular traversal
if (eleInRight > 0) {
rightSum = presum[N - 1]
- presum[i]
+ presum[K - eleInRight - 1];
}
else {
rightSum = presum[K - eleInRight - 1];
}
}
// Left part
int leftSum = 0;
// When more than k-elements
// are in left
if (i - K > 0)
leftSum = presum[i - 1]
- presum[i - K - 1];
// When exact k-elements are in left
else if (i - K == 0) {
leftSum = presum[i - 1];
}
// When some are in left some
// needs circular traversal
else {
int eleInLeft = i;
if (eleInLeft > 0) {
leftSum = presum[i - 1]
+ presum[N - 1]
- presum[N - 1 - (K - eleInLeft)];
}
else {
leftSum = presum[N - 1]
- presum[N - 1 - K];
}
}
Console.Write(((arr[i] + leftSum + rightSum)
* 1.0) / (2 * K + 1) + " ");
}
}
// Driver code
public static void Main()
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = arr.Length;
average(arr, N, K);
}
}
// This code is contributed by Shubham Singh
Javascript
4.85714 4.57143 4.28571 4 5 6 5.71429 5.42857 5.14286
时间复杂度: O(N*K)
辅助空间: O(1)
有效方法:为了降低时间复杂度,可以使用前缀和的概念,其中前缀和数组(比如 preSum[])的计算方式类似于 preSum[i] = arr[0] + 。 . . + arr[i]。并且使用 preSum[] 数组可以轻松计算每个元素的平均值,而无需在每次迭代中遍历 (2K + 1) 个元素。计算每个元素的前K个元素(leftSum)和K个下一个元素(rightSum)之和的条件如下:
Calculation for sum of K-elements in right:
- If there are K-elements present in right:
rightSum = preSum[i + k] – preSum[i]; - If no elements are in right:
rightSum = preSum[k – 1]; - If some elements are in right and some needs circular traversal:
eleInRight = n – i – 1;
rightSum = presum[n – 1] – presum[i] + presum[k – eleInRight – 1];
Calculation for sum of K-elements in left:
- If there are more than K-elements present in left:
leftSum = preSum[i – 1] – preSum[i – k – 1]; - If only k-elements are present in left:
leftSum = preSum[i – 1]; - if no elements are in left:
leftSum = preSum[n – 1] – preSum[n – 1 – k]; - If some elements are in left and some needs circular traversal:
eleInLeft = i
leftSum = preSum[i – 1] + preSum[n – 1] – preSum[n – 1 – (k – eleInLeft)];
按照下面提到的步骤来实现它:
- 迭代数组创建前缀和数组。
- 对于每个元素,获取观察结果中显示的左右总和并计算平均值。
下面是上述方法的实现:
C++
// C++ code to implement the above approach
#include
using namespace std;
// Function to calculate the average
void average(int arr[], int N, int K)
{
int presum[N];
presum[0] = arr[0];
for (int i = 1; i < N; i++) {
presum[i] = presum[i - 1] + arr[i];
}
for (int i = 0; i < N; i++) {
// Right part
int rightSum = 0;
// When all k-elements are
// in right
if (i + K < N)
rightSum = presum[i + K]
- presum[i];
else {
int eleInRight = N - i - 1;
// When some are in right and
// some needs circular traversal
if (eleInRight > 0) {
rightSum = presum[N - 1]
- presum[i]
+ presum[K - eleInRight - 1];
}
else {
rightSum = presum[K - eleInRight - 1];
}
}
// Left part
int leftSum = 0;
// When more than k-elements
// are in left
if (i - K > 0)
leftSum = presum[i - 1]
- presum[i - K - 1];
// When exact k-elements are in left
else if (i - K == 0) {
leftSum = presum[i - 1];
}
// When some are in left some
// needs circular traversal
else {
int eleInLeft = i;
if (eleInLeft > 0) {
leftSum = presum[i - 1]
+ presum[N - 1]
- presum[N - 1 - (K - eleInLeft)];
}
else {
leftSum = presum[N - 1]
- presum[N - 1 - K];
}
}
cout << ((arr[i] + leftSum + rightSum)
* 1.0)
/ (2 * K + 1)
<< " ";
}
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = sizeof(arr) / sizeof(int);
average(arr, N, K);
return 0;
}
Java
// Java code to implement the above approach
import java.util.*;
public class GFG
{
// Function to calculate the average
static void average(int arr[], int N, int K)
{
int presum[] = new int[N];
presum[0] = arr[0];
for (int i = 1; i < N; i++) {
presum[i] = presum[i - 1] + arr[i];
}
for (int i = 0; i < N; i++) {
// Right part
int rightSum = 0;
// When all k-elements are
// in right
if (i + K < N)
rightSum = presum[i + K]
- presum[i];
else {
int eleInRight = N - i - 1;
// When some are in right and
// some needs circular traversal
if (eleInRight > 0) {
rightSum = presum[N - 1]
- presum[i]
+ presum[K - eleInRight - 1];
}
else {
rightSum = presum[K - eleInRight - 1];
}
}
// Left part
int leftSum = 0;
// When more than k-elements
// are in left
if (i - K > 0)
leftSum = presum[i - 1]
- presum[i - K - 1];
// When exact k-elements are in left
else if (i - K == 0) {
leftSum = presum[i - 1];
}
// When some are in left some
// needs circular traversal
else {
int eleInLeft = i;
if (eleInLeft > 0) {
leftSum = presum[i - 1]
+ presum[N - 1]
- presum[N - 1 - (K - eleInLeft)];
}
else {
leftSum = presum[N - 1]
- presum[N - 1 - K];
}
}
System.out.print(((arr[i] + leftSum + rightSum)
* 1.0)
/ (2 * K + 1)
+ " ");
}
}
// Driver code
public static void main(String args[])
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = arr.length;
average(arr, N, K);
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python code to implement the above approach
# Function to calculate the average
def average(arr, N, K):
presum = [0]*N
presum[0] = arr[0]
for i in range(1,N):
presum[i] = presum[i - 1] + arr[i]
for i in range(0,N):
# Right part
rightSum = 0
# When all k-elements are
# in right
if (i + K < N):
rightSum = presum[i + K] - presum[i]
else:
eleInRight = N - i - 1
# When some are in right and
# some needs circular traversal
if (eleInRight > 0):
rightSum = presum[N - 1] - presum[i] + presum[K - eleInRight - 1]
else:
rightSum = presum[K - eleInRight - 1]
# Left part
leftSum = 0
# When more than k-elements
# are in left
if (i - K > 0):
leftSum = presum[i - 1] - presum[i - K - 1]
# When exact k-elements are in left
elif (i - K == 0):
leftSum = presum[i - 1]
# When some are in left some
# needs circular traversal
else:
eleInLeft = i
if (eleInLeft > 0):
leftSum = presum[i - 1] + presum[N - 1] - presum[N - 1 - (K - eleInLeft)]
else:
leftSum = presum[N - 1] - presum[N - 1 - K]
print("{:.5f}".format(((arr[i] + leftSum + rightSum) * 1.0) / (2 * K + 1)),end = " ")
# Driver code
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
K = 3
N = len(arr)
average(arr, N, K)
# This code is contributed by Shubham Singh
C#
// C# code to implement the above approach
using System;
public class GFG{
// Function to calculate the average
static void average(int[] arr, int N, int K)
{
int[] presum = new int[N];
presum[0] = arr[0];
for (int i = 1; i < N; i++) {
presum[i] = presum[i - 1] + arr[i];
}
for (int i = 0; i < N; i++) {
// Right part
int rightSum = 0;
// When all k-elements are
// in right
if (i + K < N)
rightSum = presum[i + K]
- presum[i];
else {
int eleInRight = N - i - 1;
// When some are in right and
// some needs circular traversal
if (eleInRight > 0) {
rightSum = presum[N - 1]
- presum[i]
+ presum[K - eleInRight - 1];
}
else {
rightSum = presum[K - eleInRight - 1];
}
}
// Left part
int leftSum = 0;
// When more than k-elements
// are in left
if (i - K > 0)
leftSum = presum[i - 1]
- presum[i - K - 1];
// When exact k-elements are in left
else if (i - K == 0) {
leftSum = presum[i - 1];
}
// When some are in left some
// needs circular traversal
else {
int eleInLeft = i;
if (eleInLeft > 0) {
leftSum = presum[i - 1]
+ presum[N - 1]
- presum[N - 1 - (K - eleInLeft)];
}
else {
leftSum = presum[N - 1]
- presum[N - 1 - K];
}
}
Console.Write(((arr[i] + leftSum + rightSum)
* 1.0) / (2 * K + 1) + " ");
}
}
// Driver code
public static void Main()
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int K = 3;
int N = arr.Length;
average(arr, N, K);
}
}
// This code is contributed by Shubham Singh
Javascript
4.85714 4.57143 4.28571 4 5 6 5.71429 5.42857 5.14286
时间复杂度: O(N)
辅助空间: O(N)