查找 3D 数组的给定单元格之间的总和
先决条件:前缀和 - 3D
给定一个3 维整数数组arr[L][R][C](其中 L、R 和 C 是数组的维数)和 6 个整数 D、E、F、X、Y、Z,求和arr[D][E][F]和arr[X][Y][Z]之间的整数。
例子:
Input:
A[L][R][C]:
{{ { 1, 1, 1, 1 }
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 }
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 }
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 }
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } }};
A: 1, B: 1, C: 1, X: 1, Y: 1, Z: 1
Output: 27
Explanation:
The sum between arr(1, 1, 1) and arr(3, 3, 3) is 27
方法:
- 计算给定数组 arr [L][R][C]的前缀和,并将其存储在变量prefixSum 中(请参阅this for reference) 。
- 创建一个变量 sum,它将存储答案,即 arr[D][E][F] 和 arr[X][Y][Z] 之间的总和,并使用 prefixSum 对其进行初始化,直到 X、Y、Z。所以,总和=prefixSum[X][Y][Z] 。
- 现在,只需删除此前缀总和中不需要的单元格的值。这可以通过以下方式完成:
- 删除前缀和直到(D-1,Y,Z):从所需区域的左侧删除不必要的单元格。
- Remove prefix sum until (X, E-1, Z):从每一层的底部删除不需要的单元格,不存在于所需区域。
- 删除前缀和直到(X,Y,F-1):删除所需区域下方存在的不必要层。
- 现在(D-1,E-1,Z),(X,E-1,F-1),(D-1,Y,F-1)下面的区域被删除了两次。为了弥补这一点,将前缀总和添加到总和中,直到所有这些点。
- 现在,在对删除的单元格进行两次补偿的同时,再次考虑 (D-1, E-1, F-1) 以下的单元格。删除它们以获得最终答案。
下面是上述方法的实现:
C++
// C++ program for the above approach.
#include
using namespace std;
// Declaring size of the array
#define L 4 // Layer
#define R 4 // Row
#define C 4 // Column
// Calculating prefix sum array
void prefixSum3d(
vector > >& arr,
vector > >& prefixSum)
{
// Step 0:
prefixSum[0][0][0] = arr[0][0][0];
// Step 1: Filling the first row,
// column, and pile of ceils.
// Using prefix sum of 1d array
for (int i = 1; i < L; i++)
prefixSum[i][0][0]
= prefixSum[i - 1][0][0] + arr[i][0][0];
for (int i = 1; i < R; i++)
prefixSum[0][i][0]
= prefixSum[0][i - 1][0] + arr[0][i][0];
for (int i = 1; i < C; i++)
prefixSum[0][0][i]
= prefixSum[0][0][i - 1] + arr[0][0][i];
// Step 2: Filling the cells
// of sides(made up using cells)
// which have common element arr[0][0][0].
// using prefix sum on 2d array
for (int k = 1; k < L; k++) {
for (int i = 1; i < R; i++) {
prefixSum[k][i][0]
= arr[k][i][0] + prefixSum[k - 1][i][0]
+ prefixSum[k][i - 1][0]
- prefixSum[k - 1][i - 1][0];
}
}
for (int i = 1; i < R; i++) {
for (int j = 1; j < C; j++) {
prefixSum[0][i][j]
= arr[0][i][j] + prefixSum[0][i - 1][j]
+ prefixSum[0][i][j - 1]
- prefixSum[0][i - 1][j - 1];
}
}
for (int j = 1; j < C; j++) {
for (int k = 1; k < L; k++) {
prefixSum[k][0][j]
= arr[k][0][j] + prefixSum[k - 1][0][j]
+ prefixSum[k][0][j - 1]
- prefixSum[k - 1][0][j - 1];
}
}
// Step 3: Filling value
// in remaining cells using formula
for (int k = 1; k < L; k++) {
for (int i = 1; i < R; i++) {
for (int j = 1; j < C; j++) {
prefixSum[k][i][j]
= arr[k][i][j]
+ prefixSum[k - 1][i][j]
+ prefixSum[k][i - 1][j]
+ prefixSum[k][i][j - 1]
- prefixSum[k - 1][i - 1][j]
- prefixSum[k][i - 1][j - 1]
- prefixSum[k - 1][i][j - 1]
+ prefixSum[k - 1][i - 1][j - 1];
}
}
}
}
int calculateSum(
vector > >& arr,
vector > >& prefixSum,
int D, int E, int F, int X, int Y, int Z)
{
// store prefix sum up to arr[X][Y][Z]:
int sum = prefixSum[X][Y][Z];
// Remove prefix sum till D, E, F.
if (D > 0) {
sum -= prefixSum[D - 1][Y][Z];
}
if (E > 0) {
sum -= prefixSum[X][E - 1][Z];
}
if (F > 0) {
sum -= prefixSum[X][Y][F - 1];
}
// Add to compensate cells removed multiple times.
if (D > 0 && E > 0) {
sum += prefixSum[D - 1][E - 1][Z];
}
if (E > 0 && F > 0) {
sum += prefixSum[X][E - 1][F - 1];
}
if (F > 0 && D > 0) {
sum += prefixSum[D - 1][Y][F - 1];
}
// Removing cells added twice in the above step.
if (D > 0 && E > 0 && F > 0) {
sum -= prefixSum[D - 1][E - 1][F - 1];
}
return sum;
}
// Driver Code
int main()
{
// Given 3D array:
vector > > arr(
L, vector >(R, vector(C)));
arr = { { { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } } };
// To store the prefixSum
vector > > prefixSum(
L, vector >(R, vector(C)));
// To calculate the prefixSum
prefixSum3d(arr, prefixSum);
int D, E, F, X, Y, Z;
D = 1;
E = 1;
F = 1;
X = 3;
Y = 3;
Z = 3;
cout << calculateSum(arr, prefixSum, D, E, F, X, Y, Z);
return 0;
}
Java
// Java program for the above approach.
import java.util.*;
class GFG{
// Declaring size of the array
static final int L = 4; // Layer
static final int R = 4; // Row
static final int C = 4; // Column
// Calculating prefix sum array
static void prefixSum3d(
int [][][] arr,
int [][][] prefixSum)
{
// Step 0:
prefixSum[0][0][0] = arr[0][0][0];
// Step 1: Filling the first row,
// column, and pile of ceils.
// Using prefix sum of 1d array
for (int i = 1; i < L; i++)
prefixSum[i][0][0]
= prefixSum[i - 1][0][0] + arr[i][0][0];
for (int i = 1; i < R; i++)
prefixSum[0][i][0]
= prefixSum[0][i - 1][0] + arr[0][i][0];
for (int i = 1; i < C; i++)
prefixSum[0][0][i]
= prefixSum[0][0][i - 1] + arr[0][0][i];
// Step 2: Filling the cells
// of sides(made up using cells)
// which have common element arr[0][0][0].
// using prefix sum on 2d array
for (int k = 1; k < L; k++) {
for (int i = 1; i < R; i++) {
prefixSum[k][i][0]
= arr[k][i][0] + prefixSum[k - 1][i][0]
+ prefixSum[k][i - 1][0]
- prefixSum[k - 1][i - 1][0];
}
}
for (int i = 1; i < R; i++) {
for (int j = 1; j < C; j++) {
prefixSum[0][i][j]
= arr[0][i][j] + prefixSum[0][i - 1][j]
+ prefixSum[0][i][j - 1]
- prefixSum[0][i - 1][j - 1];
}
}
for (int j = 1; j < C; j++) {
for (int k = 1; k < L; k++) {
prefixSum[k][0][j]
= arr[k][0][j] + prefixSum[k - 1][0][j]
+ prefixSum[k][0][j - 1]
- prefixSum[k - 1][0][j - 1];
}
}
// Step 3: Filling value
// in remaining cells using formula
for (int k = 1; k < L; k++) {
for (int i = 1; i < R; i++) {
for (int j = 1; j < C; j++) {
prefixSum[k][i][j]
= arr[k][i][j]
+ prefixSum[k - 1][i][j]
+ prefixSum[k][i - 1][j]
+ prefixSum[k][i][j - 1]
- prefixSum[k - 1][i - 1][j]
- prefixSum[k][i - 1][j - 1]
- prefixSum[k - 1][i][j - 1]
+ prefixSum[k - 1][i - 1][j - 1];
}
}
}
}
static int calculateSum(
int [][][] arr,
int [][][] prefixSum,
int D, int E, int F, int X, int Y, int Z)
{
// store prefix sum up to arr[X][Y][Z]:
int sum = prefixSum[X][Y][Z];
// Remove prefix sum till D, E, F.
if (D > 0) {
sum -= prefixSum[D - 1][Y][Z];
}
if (E > 0) {
sum -= prefixSum[X][E - 1][Z];
}
if (F > 0) {
sum -= prefixSum[X][Y][F - 1];
}
// Add to compensate cells removed multiple times.
if (D > 0 && E > 0) {
sum += prefixSum[D - 1][E - 1][Z];
}
if (E > 0 && F > 0) {
sum += prefixSum[X][E - 1][F - 1];
}
if (F > 0 && D > 0) {
sum += prefixSum[D - 1][Y][F - 1];
}
// Removing cells added twice in the above step.
if (D > 0 && E > 0 && F > 0) {
sum -= prefixSum[D - 1][E - 1][F - 1];
}
return sum;
}
// Driver Code
public static void main(String[] args)
{
// Given 3D array:
int [][][] arr = { { { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } } };
// To store the prefixSum
int [][][] prefixSum= new int[L][R][C];
// To calculate the prefixSum
prefixSum3d(arr, prefixSum);
int D, E, F, X, Y, Z;
D = 1;
E = 1;
F = 1;
X = 3;
Y = 3;
Z = 3;
System.out.print(calculateSum(arr, prefixSum, D, E, F, X, Y, Z));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program for the above approach.
# Declaring size of the array
L = 4 # Layer
R = 4 # Row
C = 4 # Column
# Calculating prefix sum array
def prefixSum3d(arr, prefixSum):
# Step 0:
prefixSum[0][0][0] = arr[0][0][0]
# Step 1: Filling the first row,
# column, and pile of ceils.
# Using prefix sum of 1d array
for i in range(1, L):
prefixSum[i][0][0] = prefixSum[i - 1][0][0] + arr[i][0][0]
for i in range(1, R):
prefixSum[0][i][0] = prefixSum[0][i - 1][0] + arr[0][i][0]
for i in range(1, C):
prefixSum[0][0][i] = prefixSum[0][0][i - 1] + arr[0][0][i]
# Step 2: Filling the cells
# of sides(made up using cells)
# which have common element arr[0][0][0].
# using prefix sum on 2d array
for k in range(1, L):
for i in range(1, R):
prefixSum[k][i][0] = arr[k][i][0] + prefixSum[k - 1][i][0] + \
prefixSum[k][i - 1][0] - prefixSum[k - 1][i - 1][0]
for i in range(1, R):
for j in range(1, C):
prefixSum[0][i][j] = arr[0][i][j] + prefixSum[0][i - 1][j] + \
prefixSum[0][i][j - 1] - prefixSum[0][i - 1][j - 1]
for j in range(1, C):
for k in range(1, L):
prefixSum[k][0][j] = arr[k][0][j] + prefixSum[k - 1][0][j] + \
prefixSum[k][0][j - 1] - prefixSum[k - 1][0][j - 1]
# Step 3: Filling value
# in remaining cells using formula
for k in range(1, L):
for i in range(1, R):
for j in range(1, C):
prefixSum[k][i][j] = arr[k][i][j] + prefixSum[k - 1][i][j] + prefixSum[k][i - 1][j] + prefixSum[k][i][j - 1] - \
prefixSum[k - 1][i - 1][j] - prefixSum[k][i - 1][j - 1] - \
prefixSum[k - 1][i][j - 1] + prefixSum[k - 1][i - 1][j - 1]
def calculateSum(arr, prefixSum, D, E, F, X, Y, Z):
# store prefix sum up to arr[X][Y][Z]:
sum = prefixSum[X][Y][Z]
# Remove prefix sum till D, E, F.
if (D > 0):
sum -= prefixSum[D - 1][Y][Z]
if (E > 0):
sum -= prefixSum[X][E - 1][Z]
if (F > 0):
sum -= prefixSum[X][Y][F - 1]
# Add to compensate cells removed multiple times.
if (D > 0 and E > 0):
sum += prefixSum[D - 1][E - 1][Z]
if (E > 0 and F > 0):
sum += prefixSum[X][E - 1][F - 1]
if (F > 0 and D > 0):
sum += prefixSum[D - 1][Y][F - 1]
# Removing cells added twice in the above step.
if (D > 0 and E > 0 and F > 0):
sum -= prefixSum[D - 1][E - 1][F - 1]
return sum
# Driver Code
if __name__ == "__main__":
# Given 3D array:
arr = [[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]]
# To store the prefixSum
prefixSum = [[[0 for _ in range(C)] for _ in range(R)] for _ in range(L)]
# To calculate the prefixSum
prefixSum3d(arr, prefixSum)
D = 1
E = 1
F = 1
X = 3
Y = 3
Z = 3
print(calculateSum(arr, prefixSum, D, E, F, X, Y, Z))
# This code is contributed by rakeshsahni
C#
// C# program for the above approach.
using System;
public class GFG{
// Declaring size of the array
static readonly int L = 4; // Layer
static readonly int R = 4; // Row
static readonly int C = 4; // Column
// Calculating prefix sum array
static void prefixSum3d(
int [,,] arr,
int [,,] prefixSum)
{
// Step 0:
prefixSum[0,0,0] = arr[0,0,0];
// Step 1: Filling the first row,
// column, and pile of ceils.
// Using prefix sum of 1d array
for (int i = 1; i < L; i++)
prefixSum[i,0,0]
= prefixSum[i - 1,0,0] + arr[i,0,0];
for (int i = 1; i < R; i++)
prefixSum[0,i,0]
= prefixSum[0,i - 1,0] + arr[0,i,0];
for (int i = 1; i < C; i++)
prefixSum[0,0,i]
= prefixSum[0,0,i - 1] + arr[0,0,i];
// Step 2: Filling the cells
// of sides(made up using cells)
// which have common element arr[0,0,0].
// using prefix sum on 2d array
for (int k = 1; k < L; k++) {
for (int i = 1; i < R; i++) {
prefixSum[k,i,0]
= arr[k,i,0] + prefixSum[k - 1,i,0]
+ prefixSum[k,i - 1,0]
- prefixSum[k - 1,i - 1,0];
}
}
for (int i = 1; i < R; i++) {
for (int j = 1; j < C; j++) {
prefixSum[0,i,j]
= arr[0,i,j] + prefixSum[0,i - 1,j]
+ prefixSum[0,i,j - 1]
- prefixSum[0,i - 1,j - 1];
}
}
for (int j = 1; j < C; j++) {
for (int k = 1; k < L; k++) {
prefixSum[k,0,j]
= arr[k,0,j] + prefixSum[k - 1,0,j]
+ prefixSum[k,0,j - 1]
- prefixSum[k - 1,0,j - 1];
}
}
// Step 3: Filling value
// in remaining cells using formula
for (int k = 1; k < L; k++) {
for (int i = 1; i < R; i++) {
for (int j = 1; j < C; j++) {
prefixSum[k,i,j]
= arr[k,i,j]
+ prefixSum[k - 1,i,j]
+ prefixSum[k,i - 1,j]
+ prefixSum[k,i,j - 1]
- prefixSum[k - 1,i - 1,j]
- prefixSum[k,i - 1,j - 1]
- prefixSum[k - 1,i,j - 1]
+ prefixSum[k - 1,i - 1,j - 1];
}
}
}
}
static int calculateSum(
int [,,] arr,
int [,,] prefixSum,
int D, int E, int F, int X, int Y, int Z)
{
// store prefix sum up to arr[X,Y,Z]:
int sum = prefixSum[X,Y,Z];
// Remove prefix sum till D, E, F.
if (D > 0) {
sum -= prefixSum[D - 1,Y,Z];
}
if (E > 0) {
sum -= prefixSum[X,E - 1,Z];
}
if (F > 0) {
sum -= prefixSum[X,Y,F - 1];
}
// Add to compensate cells removed multiple times.
if (D > 0 && E > 0) {
sum += prefixSum[D - 1,E - 1,Z];
}
if (E > 0 && F > 0) {
sum += prefixSum[X,E - 1,F - 1];
}
if (F > 0 && D > 0) {
sum += prefixSum[D - 1,Y,F - 1];
}
// Removing cells added twice in the above step.
if (D > 0 && E > 0 && F > 0) {
sum -= prefixSum[D - 1,E - 1,F - 1];
}
return sum;
}
// Driver Code
public static void Main(String[] args)
{
// Given 3D array:
int [,,] arr = { { { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } },
{ { 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 1, 1, 1, 1 } } };
// To store the prefixSum
int [,,] prefixSum= new int[L,R,C];
// To calculate the prefixSum
prefixSum3d(arr, prefixSum);
int D, E, F, X, Y, Z;
D = 1;
E = 1;
F = 1;
X = 3;
Y = 3;
Z = 3;
Console.Write(calculateSum(arr, prefixSum, D, E, F, X, Y, Z));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出
27
时间复杂度: O(L*R*C)
辅助空间: O(L*R*C)