Zero to Hero
article thumbnail
Published 2021. 9. 7. 18:44
1314. Matrix Block Sum Algorithm
 

Matrix Block Sum - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com

2차원 배열과 양의 정수 k가 주어진다.

2차원 배열의 특정한 좌표 (i, j)에 대해서 해당 좌표를 중심으로 k 길이만큼의 범위에 해당하는 모든 값을 더한 값을 저장한 배열을 반환하는 문제다.

 

예시

Input: mat = [[1,2,3],[4,5,6],[7,8,9]], k = 1
Output: [[12,21,16],[27,45,33],[24,39,28]]

[1,2,3]
[4,5,6]
[7,8,9]

이렇게 생긴 배열을 길이 k 만큼의 범위에 해당하는 모든 값을 더하면

[12,21,16]
[27,45,33]
[24,39,28]

이렇게 된다.

k = 2인 경우는

[45,45,45]
[45,45,45]
[45,45,45]

이렇게 된다.

접근법

문제를 보고 바로 매번 탐색해서 계산해 넣으면 시간 초과가 나는 문제라고 생각했다.

2차원 누적합을 이용해 해결하기로 했다.

 

1. 2D prefix sum(2차원 누적합)

from typing import *


class Solution:
    def matrixBlockSum(self, mat: List[List[int]], k: int) -> List[List[int]]:
        height, width = len(mat), len(mat[0])
        new_mat = [[0] * (width + 2 * k) for _ in range(height + 2 * k)]
        answer = [[0] * width for _ in range(height)]

        for i in range(height):
            for j in range(width):
                new_mat[i + k][j + k] = mat[i][j]

        height2, width2 = height + 2 * k, width + 2 * k
        for i in range(1, height2):
            for j in range(1, width2):
                new_mat[i][j] += new_mat[i][j - 1]

        for j in range(1, width2):
            for i in range(1, height2):
                new_mat[i][j] += new_mat[i - 1][j]

        def sol(x1, y1, x2, y2):
            result = new_mat[x2][y2]
            a = new_mat[x2][y1 - 1] if y1 - 1 >= 0 else 0
            b = new_mat[x1 - 1][y2] if x1 - 1 >= 0 else 0
            c = new_mat[x1 - 1][y1 - 1] if x1 - 1 >= 0 and y1 - 1 >= 0 else 0

            return result - a - b + c

        for i in range(height):
            for j in range(width):
                x1, y1 = i, j
                x2, y2 = i + 2 * k, j + 2 * k
                answer[i][j] = sol(x1, y1, x2, y2)

        return answer

주어진 2차원 배열을 한 번 탐색해 2차원 누적합 배열을 만들 수 있다.

이후 구한 2차원 배열을 이용해 해당 범위에 대한 값을 O(1)로 구할 수 있다.

 

구현 방법 및 시뮬레이션은 아래와 같다.

주어진 배열에 k = 1 만큼 zero-padding을 한다. -> 0-padding 배열
[0, 0, 0, 0, 0]
[0, 1, 2, 3, 0]
[0, 4, 5, 6, 0]
[0, 7, 8, 9, 0]
[0, 0, 0, 0, 0]

만든 배열을 이용해 2차원 누적합 배열을 만든다.
[0, 0, 0, 0, 0]
[0, 1, 3, 6, 6]
[0, 5, 12, 21, 21]
[0, 12, 27, 45, 45]
[0, 12, 27, 45, 45]

2차원 누적합 배열을 이용해 원하는 값을 구한다.
0,0에 들어갈 값은 0-padding 배열의 (0,0) ~ (2,2) 범위의 값의 합
0,1에 들어갈 값은 0-padding 배열의 (0,1) ~ (2,3) 범위의 값의 합
0,2에 들어갈 값은 0-padding 배열의 (0,2) ~ (2,4) 범위의 값의 합
1,0에 들어갈 값은 0-padding 배열의 (1,0) ~ (3,2) 범위의 값의 합
1,1에 들어갈 값은 0-padding 배열의 (1,1) ~ (3,3) 범위의 값의 합
1,2에 들어갈 값은 0-padding 배열의 (1,2) ~ (3,4) 범위의 값의 합
2,0에 들어갈 값은 0-padding 배열의 (2,0) ~ (4,2) 범위의 값의 합
2,1에 들어갈 값은 0-padding 배열의 (2,1) ~ (4,3) 범위의 값의 합
2,2에 들어갈 값은 0-padding 배열의 (2,2) ~ (4,4) 범위의 값의 합

[12, 21, 16]
[27, 45, 33]
[24, 39, 28]

 

주어진 배열에 k = 2 만큼 zero-padding을 한다. -> 0-padding 배열
[0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 2, 3, 0, 0]
[0, 0, 4, 5, 6, 0, 0]
[0, 0, 7, 8, 9, 0, 0]
[0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0]

만든 배열을 이용해 2차원 누적합 배열을 만든다.
[0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 3, 6, 6, 6]
[0, 0, 5, 12, 21, 21, 21]
[0, 0, 12, 27, 45, 45, 45]
[0, 0, 12, 27, 45, 45, 45]
[0, 0, 12, 27, 45, 45, 45]

2차원 누적합 배열을 이용해 원하는 값을 구한다.
0,0에 들어갈 값은 0-padding 배열의 (0,0) ~ (4,4) 범위의 값의 합
0,1에 들어갈 값은 0-padding 배열의 (0,1) ~ (4,5) 범위의 값의 합
0,2에 들어갈 값은 0-padding 배열의 (0,2) ~ (4,6) 범위의 값의 합
1,0에 들어갈 값은 0-padding 배열의 (1,0) ~ (5,4) 범위의 값의 합
1,1에 들어갈 값은 0-padding 배열의 (1,1) ~ (5,5) 범위의 값의 합
1,2에 들어갈 값은 0-padding 배열의 (1,2) ~ (5,6) 범위의 값의 합
2,0에 들어갈 값은 0-padding 배열의 (2,0) ~ (6,4) 범위의 값의 합
2,1에 들어갈 값은 0-padding 배열의 (2,1) ~ (6,5) 범위의 값의 합
2,2에 들어갈 값은 0-padding 배열의 (2,2) ~ (6,6) 범위의 값의 합

[45, 45, 45]
[45, 45, 45]
[45, 45, 45]

 

2차원 누적합 배열 관련 포스팅은 아래 링크를 참고할 것.

 

2차원 누적합, 부분합 구하기

누적합의 필요성 알고리즘 문제를 풀다보면 배열의 부분합을 빠르게 구해야 하는 경우가 있다. 필요할 때 마다 구하게 되면 구할 때 마다 //(O(N)//)의 시간 복잡도를 갖는다. 종만북 1번 문제 페스

eine.tistory.com

'Algorithm' 카테고리의 다른 글

925. Long Pressed Name  (0) 2021.09.16
941. Valid Mountain Array  (0) 2021.09.14
861. Score After Flipping Matrix  (0) 2021.09.06
1829. Maximum XOR for Each Query  (0) 2021.09.04
1641. Count Sorted Vowel Strings  (0) 2021.09.02
profile

Zero to Hero

@Doljae

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!