1. 문제
programmers.co.kr/learn/courses/30/lessons/60059
코딩테스트 연습 - 자물쇠와 열쇠
[[0, 0, 0], [1, 0, 0], [0, 1, 1]] [[1, 1, 1], [1, 1, 0], [1, 0, 1]] true
programmers.co.kr
문제 설명
제한 사항
입출력 예
2. 어떻게 풀까?
lock
을 가만히 두고key
를 끝에서1 x 1
에서n x n
까지 이동시키면서 홈에 맞는지 확인한다.- 맞지 않는다면
key
를 90도 회전한다. key
를 4번 회전시켜도 그대로라면 false를 리턴한다.
- 위와 같이 생각했는데, 코드로 어떻게 구현해야 할지 감이 안 와서 고민하다가 결국 다른 사람이 푼 코드를 참고했다.
- 코드를 보니, 반대로 생각했다.
key
는 가만히 두고,lock
을 움직이면서key
와 맞는지 체크한다. - 코드로 구현하기 위해서
key
에 padding을 했다.
3. 코드
테스트 코드
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import org.junit.Test;
public class SolutionTest {
@Test
public void test1() {
int[][] key = {
{0, 0, 0},
{1, 0, 0},
{0, 1, 1}
};
int[][] lock = {
{1, 1, 1},
{1, 1, 0},
{1, 0, 1}
};
assertThat(new Solution().solution(key, lock), is(true));
}
}
실제 코드
public class Solution {
public boolean solution(int[][] key, int[][] lock) {
int padSize = lock.length - 1;
for (int i = 0; i < 4; i++) {
key = rotate(key);
int[][] paddedKey = pad(key, padSize);
for (int j = 0; j < paddedKey.length - padSize; j++) {
for (int k = 0; k < paddedKey.length - padSize; k++) {
if (isValid(lock, paddedKey, j, k)) {
return true;
}
}
}
}
return false;
}
private boolean isValid(int[][] lock, int[][] paddedKey, int j, int k) {
for (int l = 0; l < lock.length; l++) {
for (int m = 0; m < lock.length; m++) {
if (lock[l][m] + paddedKey[j + l][k + m] != 1) {
return false;
}
}
}
return true;
}
private int[][] pad(int[][] key, int padSize) {
int[][] result = new int[key.length + padSize * 2][key.length + padSize * 2];
for (int i = 0; i < key.length; i++) {
for (int j = 0; j < key.length; j++) {
result[padSize + i][padSize + j] = key[i][j];
}
}
return result;
}
private int[][] rotate(int[][] key) {
int[][] result = new int[key.length][key.length];
for (int i = 0; i < key.length; i++) {
for (int j = 0; j < key.length; j++) {
result[i][j] = key[key.length - 1 - j][i];
}
}
return result;
}
private int[][] copy(int[][] key) {
int[][] result = new int[key.length][key.length];
for (int i = 0; i < key.length; i++) {
for (int j = 0; j < key.length; j++) {
result[i][j] = key[i][j];
}
}
return result;
}
}
rotate()
에서key
를 오른쪽 90도로 회전한다.pad()
에서lock
의length - 1
만큼 상하좌우로 추가하여 padding 해준다.pad
된key
의 0부터 끝까지 가는 게 아니라key
까지만 이동한다. 더 이동하면lock
이 pad범위를 벗어나기 때문
4. 느낀 점
- 문제를 처음 보고, 어렵지만 할 수 있겠다고 생각했다. 실제로 문제 해결 방법은 맞다고 생각한다.
- 근데 이것을 코드로 구현하는 과정이 너무 어렵다.. 이걸 잘해야 level 3 문제들을 풀 수 있을 듯.
'Coding Test > Programmers' 카테고리의 다른 글
[Programmers] 단어 변환 (Java) (0) | 2022.01.26 |
---|---|
프로그래머스 - 정수 삼각형 (java) (0) | 2021.02.25 |
프로그래머스 - N으로 표현(02/02) (java) (0) | 2021.02.02 |
프로그래머스 - 추석 트래픽(01/23) (java) (0) | 2021.01.23 |
프로그래머스 - 압축 (01/11) (java) (0) | 2021.01.11 |