나타날 수 있는 모든 모양의 키를 자물쇠와 대조해야하는 문제다. 따라서 모든 경우의 수를 다 구하는 것이 핵심이다.
0도
, 90도
, 180도
, 270도
로 회전하여 나타나는 모양은 단순 이동으로 모두 포함할 수 없다. 따라서 원본과 3가지 각도로 회전한 모양을 시작점으로 이동한다.result[c][origin.length - 1 - r] = origin[r][c];
[0][0]
만 겹치는 경우부터 [len - 1][len - 1]
만 겹치는 경우까지 모두 해보면 된다.(키의 길이 - 1) * 2
다.실제 시험에서 이런 문제를 접하면 과연 생각해낼 수 있을까싶다. 차근 차근 아이디어를 발전시켜나가는 연습이 필요하다.
import java.util.*;
class Solution {
public boolean solution(int[][] key, int[][] lock) {
int size = lock.length - 1;
for(int d = 0 ; d < 4 ; ++d) {
int[][] rotatedKey = rotate(d, key);
int[][] paddedKey = padding(rotatedKey, size);
for(int R = 0 ; R < paddedKey.length - size ; ++R) {
for(int C = 0 ; C < paddedKey[0].length - size ; ++C) {
boolean flag = true;
for(int r = 0 ; r < lock.length ; ++r) {
for(int c = 0 ; c < lock[0].length ; ++c) {
if(lock[r][c] == paddedKey[R + r][C + c]) flag = false;
}
}
if(flag) return true;
}
}
}
return false;
}
private int[][] padding(int[][] arr, int size) {
int[][] result = new int[arr.length + size * 2][arr[0].length + size * 2];
for(int r = 0 ; r < arr.length ; ++r) {
for(int c = 0 ; c < arr[0].length ; ++c) {
result[r + size][c + size] = arr[r][c];
}
}
return result;
}
private int[][] rotate(int cnt, int[][] arr){
if(cnt == 0) return arr;
int[][] result = null;
int[][] origin = copy(arr);
for(int i = 0 ; i < cnt ; ++i) {
result = new int[arr.length][arr[0].length];
for(int r = 0 ; r < origin.length ; ++r) {
for(int c = 0 ; c < origin[0].length ; ++c) {
result[c][origin.length - 1 - r] = origin[r][c];
}
}
origin = result;
}
return result;
}
private int[][] copy(int[][] arr){
int[][] result = new int[arr.length][arr[0].length];
for(int r = 0 ; r < arr.length ; ++r) {
for(int c = 0 ; c < arr[r].length ; ++c) {
result[r][c] = arr[r][c];
}
}
return result;
}
}