📜  查找 3D 数组的给定单元格之间的总和

📅  最后修改于: 2022-05-13 01:57:23.177000             🧑  作者: Mango

查找 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]之间的整数。

例子:

方法:

  • 计算给定数组 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)