키패드가 다음과 같이 있을 때,
1 2 3
4 5 6
7 8 9
* 0 #
키패드 입력하는 int형 배열과
오른손잡이인지 왼손잡이인지 알려주는 String형으로 입력값을 받아서
1/4/7은 왼손, 3/6/9는 오른손으로 입력하고
나머지는 가까운쪽에 있는 손으로 입력한다.
단, 거리가 같을 경우는 오른손잡이는 오른손 왼손잡이는 왼손으로 입력한다.
다른것은 어렵지 않은데 거리를 비교하는 것이 까다로운 문제였다.
거리를 어떻게 비교해주지 한참 고민해도 답이 나오지 않았다.
결국 거리를 구하는 부분만 검색해서 찾아서 풀었다.
int rightdist = Math.abs(a - right) / 3 + Math.abs(a - right) % 3;
int leftdist = Math.abs(a - left) / 3 + Math.abs(a - left) % 3;
이 공식은 딱 정해진 답은 아니므로 참고만 하자.
(공식의 출처는 이곳입니다.)
키패드의 양옆으로의 차이는 1이고, 아래위의 차이는 3인것을 이용한 공식이다.
여기서 중요한 것은 0은 11로 취급해줘야하기 때문에
*은 10, 0은 11, #은 12로 해주었다.
static String solution(int[] arr, String hand){
StringBuilder answer1 = new StringBuilder("");
String mainHand = "";
if(hand.equals("right")){
mainHand = "R";
} else {
mainHand = "L";
}
// * = 10, 0 = 11, # = 12
int left = 10;
int right = 12;
for (int a : arr) {
if(a == 0) a=11;
if (a == 1 || a == 4 || a == 7) {
answer1.append("L");
left = a;
} else if (a == 3 || a == 6 || a == 9) {
answer1.append("R");
right = a;
} else {
int leftdist = Math.abs(a - left) / 3 + Math.abs(a - left) % 3;
int rightdist = Math.abs(a - right) / 3 + Math.abs(a - right) % 3;
if (leftdist < rightdist) {
answer1.append("L");
left = a;
} else if (leftdist > rightdist) {
answer1.append("R");
right = a;
} else {
if (hand.equals("right")) {
answer1.append("R");
right = a;
} else {
answer1.append("L");
left = a;
}
}
}
}
String answer = String.valueOf(answer1);
return answer;
}
다른 분들은 어떻게 풀었는지 살펴 보자.
class Solution {
// 0부터 9까지 좌표 {y,x}
int[][] numpadPos = {
{3,1}, //0
{0,0}, //1
{0,1}, //2
{0,2}, //3
{1,0}, //4
{1,1}, //5
{1,2}, //6
{2,0}, //7
{2,1}, //8
{2,2} //9
};
//초기 위치
int[] leftPos = {3,0};
int[] rightPos = {3,2};
String hand;
public String solution(int[] numbers, String hand) {
this.hand = (hand.equals("right")) ? "R" : "L";
String answer = "";
for (int num : numbers) {
String Umji = pushNumber(num);
answer += Umji;
if(Umji.equals("L")) {leftPos = numpadPos[num]; continue;}
if(Umji.equals("R")) {rightPos = numpadPos[num]; continue;}
}
return answer;
}
//num버튼을 누를 때 어디 손을 사용하는가
private String pushNumber(int num) {
if(num==1 || num==4 || num==7) return "L";
if(num==3 || num==6 || num==9) return "R";
// 2,5,8,0 일때 어디 손가락이 가까운가
if(getDist(leftPos, num) > getDist(rightPos, num)) return "R";
if(getDist(leftPos, num) < getDist(rightPos, num)) return "L";
//같으면 손잡이
return this.hand;
}
//해당 위치와 번호 위치의 거리
private int getDist(int[] pos, int num) {
return Math.abs(pos[0]-numpadPos[num][0]) + Math.abs(pos[1]-numpadPos[num][1]);
}
}
와 키패드를 아예 2차원 배열로 좌표화해서 푼 것이 인상적이다.
그리고 내 코드와 비교했을때 왼손잡이인지 오른손잡이인지 구분하는 코드에서 나는 불필요하게 if문을 두번이나 써야했는데
위의 코드에서는 다항식으로 간단하게 사용하는 것도 배울점이다.
또 pushNumber 메소드와 getDist 메소드를 따로 정의해서 사용하는 것도 코드가 한결 깔끔해지고 가독성이 좋아졌다.
적당히 까다로우면서 쉬운문제였는데
혼자서 한번에 풀지 못한 것이 아쉬웠다.
이런 문제는 그냥 넘어가지 말고 다른 사람의 풀이를 보면서 돌이켜보니까 배울것이 많았다.
잊어버리지 않도록 기록해놓고 종종 봐야겠다.