문제
2차원 행렬 arr1과 arr2를 입력받아, arr1에 arr2를 곱한 결과를 반환하는 함수, solution을 완성해주세요.
제한사항
- 행렬 arr1, arr2의 행과 열의 길이는 2 이상 100 이하입니다.
- 행렬 arr1, arr2의 원소는 -10 이상 20 이하인 자연수입니다.
- 곱할 수 있는 배열만 주어집니다.
class Solution {
public int[][] solution(int[][] arr1, int[][] arr2) {
int[][] answer = new int[arr1.length][arr2[0].length];
for(int r = 0; r < arr1.length; r++) {
for(int i = 0; i < arr1[0].length; i++) {
for(int j = 0; j < arr2[0].length; j++) {
answer[r][j] += arr1[r][i]*arr2[i][j];
}
}
}
return answer;
}
}
레벨 2부터 왜 이렇게 수학문제가 많은 건지 모르겠다.
최대한 for문을 적게 사용해서 하고 싶었는데 아무리 생각해도 이 방법이 최선의 방법 같았다.
행렬의 곱셈은 M×K, K×N 을 무조건 만족해야 할 수 있는 연산이다.
따라서 M×N 크기의 배열을 만들어주고 연산해 준다.
일반적으로 손으로 계산할 땐, arr1[0][0]은 arr2[0][0]과 곱하고... arr[0][1]은 arr2[1][0]과 곱하고... 이런 식으로 arr1은 가로로, arr2는 세로로 움직이며 연산을 한다.
그런데 연산되는 방식을 자세히 보면 규칙이 있다.
말로 하는 것보다 예시를 들면,
구글에서 가장 이해하기 쉽다고 생각된 그림을 가져와봤다.
A[0][0]은 B[0][0~3]까지 연산해서 C에 담아두고, 이를 A[0][1]과 B[1][0~3]까지 연산한 결과를 더해서 결과물 행렬 C에 저장한다.
결국 B는 [0][0~3], [1][0~3]만 반복하고 이에 따라 A의 각 행의 첫 번째 원소, 두 번째 원소를 연산해 주는 방식이다.
결국 A의 각 행을 가져오기 위한 for문 한 번
A에서 가져온 행의 원소를 하나씩 가져오기 위한 for문 한 번
그 원소를 B의 원소들과 연산하기 위한 for문 한 번
해서 총 for문을 세 번 써야 한다.
출처
https://school.programmers.co.kr/learn/courses/30/lessons/12949