[JAVA] 키패드 누르기
< 내 풀이 >
class Solution {
static char arr[][]={{'1','2','3'},{'4','5','6'},{'7','8','9'},{'*','0','#'}};
static int distance(char start, int num){ // 현재 누르는 번호까지의 거리를 구하는 함수
int start_x=0,start_y=0;
int end_x=0,end_y=0;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
if(arr[i][j]==start){
start_x=i;
start_y=j;
}
if(arr[i][j]==(char)num+'0'){
end_x=i;
end_y=j;
}
}
}
int dist=Math.abs(end_x-start_x)+Math.abs(end_y-start_y);
return dist;
}
public String solution(int[] numbers, String hand) {
String answer = "";
char left='*'; //현재 왼손의 위치
char right='#'; //현재 오른손의 위치
for(int i=0;i<numbers.length;i++){
if(numbers[i]==1||numbers[i]==4||numbers[i]==7){
left=(char)(numbers[i]+'0');
answer+="L";
}
else if(numbers[i]==3||numbers[i]==6||numbers[i]==9){
right=(char)(numbers[i]+'0');
answer+="R";
}
else { //누르는 숫자가 2,5,8,0 일 때
int right_dist= distance(right,numbers[i]);
int left_dist=distance(left,numbers[i]);
if(right_dist==left_dist){
hand=hand.toUpperCase();
answer+=hand.charAt(0);
if(hand.charAt(0)=='R')
right=(char)(numbers[i]+'0');
else
left=(char)(numbers[i]+'0');
}
else if(right_dist<left_dist){
right=(char)(numbers[i]+'0');
answer+="R";
}
else{
left=(char)(numbers[i]+'0');
answer+="L";
}
}
}
return answer;
}
}
✏️ 풀이 방법
1. numbers 배열의 크기만큼 반복문을 돈다. ( 처음 왼손의 위치는 *, 처음 오른손의 위치는 # 이다.)
2. 번호가 1,4,7 일 경우 : 왼손의 위치 갱신, 정답을 저장하는 문자열에 "L" 추가
번호가 3,6,9 일 경우: 오른손의 위치 갱신, 정답을 저장하는 문자열에 "R" 추가
번호가 2,5,8,0 일 경우: (오른손 ~ 누르는 번호까지의 거리), (왼손 ~ 누르는 번호까지의 거리) 중 값이 작은 손으로 번호를 눌러야함
=> distance 함수 ( start 에서 num 까지의 거리를 구함)
1. 2차원 배열에 키패드의 값이 저장되어 있음
2. 매개변수로 받은 start의 위치를 찾아 start_x 와 start_y 에 저장
3. 매개변수로 받은 num의 위치를 찾아 end_x 와 end_y 에 저장
4. Math.abs(end_x-start_x)+Math.abs(end_y-start_y) 가 곧 두 값의 거리가 된다. (Math.abs => 절댓값을 구하는 함수)
- 오른손에서의 거리와 왼손에서의 거리가 같을 때 : 매개변수로 받았던 hand 의 값을 대문자로 변환한 후, 첫 문자를
answer 에 저장, R일 경우에는 오른손의 위치 갱신, L일 경우에는 왼손의 위치 갱신
- 오른손에서의 거리 < 왼손에서의 거리 : 오른손의 위치 갱신, 정답을 저장하는 문자열에 "R" 추가
- 왼손에서의 거리 < 오른손에서의 거리: 왼손의 위치 갱신, 정답을 저장하는 문자열에 "L" 추가
3. 위의 방법으로 구한 answer을 반환
< 다른 사람의 풀이 >
class Solution {
public String solution(int[] numbers, String hand) {
StringBuilder sb = new StringBuilder();
int left = 10;
int right = 12;
for (int i = 0; i < numbers.length; i++) {
int n = numbers[i];
if (n == 1 || n == 4 || n == 7) {
left = n;
sb.append("L");
}
if (n == 3 || n == 6 || n == 9) {
right = n;
sb.append("R");
}
if (n == 2 || n == 5 || n == 8 || n == 0) {
if( n == 0 ) n = 11;
int leftDiff = (Math.abs(n - left) / 3) + (Math.abs(n - left) % 3);
int rightDiff =(Math.abs(n - right) / 3) + (Math.abs(n - right) % 3);
if (leftDiff == rightDiff) {
if (hand.equals("right")) {
right = n;
sb.append("R");
}else{
left = n;
sb.append("L");
}
} else if (leftDiff > rightDiff) {
right = n;
sb.append("R");
} else {
left = n;
sb.append("L");
}
}
}
return sb.toString();
}
}
➡️ 이와 같은 방법으로 n부터 left 까지의 거리, n부터 right 까지의 거리를 구하는게 너무 똑똑한 방법인 것 같다.
✍🏻 느낀점
처음에 이 문제를 봤을 때, 거리를 어떻게 구해야할지 감이 잘 안잡혔다. 좀 생각을 해보고 2차원 배열에 값을 저장해서 풀었는데, 다른 사람의 풀이를 보고 나서 나는 왜 저 생각을 못했을까 싶었다. 또 하나 배우게 된 문제였다. 그리고 처음에 계속 답이 이상하게 나왔는데, 오른손에서의 거리와 왼손에서의 거리가 같을 때 answer에 값을 추가하고 난 후, 왼손과 오른손의 위치를 적절하게 바꿔주지 않아서 답이 계속 이상했다. 역시 문제를 꼼꼼하게 풀어야하는 것 같다. 거리 구하는 것만 잘하면 어렵지 않은 문제 같은데, 내가 처음에 너무 어렵게 생각하지 않았나싶다. 이번 문제로 또 하나 배웠으니 다음에 비슷한 문제가 나오면 겁 먹지 말자 !
참고 블로그