JAVA/알고리즘 서브 노트
[프로그래머스: JAVA] 키패드 누르기
Kamea
2022. 8. 15. 21:39
문제
스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.
이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.
맨 처음 왼손 엄지손가락은 * 키패드에 오른손 엄지손가락은 # 키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.
- 엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.
- 왼쪽 열의 3개의 숫자 1, 4, 7을 입력할 때는 왼손 엄지손가락을 사용합니다.
- 오른쪽 열의 3개의 숫자 3, 6, 9를 입력할 때는 오른손 엄지손가락을 사용합니다.
- 가운데 열의 4개의 숫자 2, 5, 8, 0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.
4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.
순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때, 각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.
[제한사항]
- numbers 배열의 크기는 1 이상 1,000 이하입니다.
- numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.
- hand는 "left" 또는 "right" 입니다.
- "left"는 왼손잡이, "right"는 오른손잡이를 의미합니다.
- 왼손 엄지손가락을 사용한 경우는 L, 오른손 엄지손가락을 사용한 경우는 R을 순서대로 이어붙여 문자열 형태로 return 해주세요.
코드
class Solution {
// 키패드 번호에 해당하는 위치값을 배열에 넣어줌
static int[][] r = {{3, 1}, {0, 0}, {0, 1}, {0, 2}, {1, 0}, {1, 1}, {1, 2}, {2, 0}, {2, 1}, {2, 2}};
public String solution(int[] numbers, String hand) {
String answer = "";
int[] dl = new int[] {3, 0}; // 왼손 좌표
int[] dr = new int[] {3, 2}; // 오른손 좌표
for(int num: numbers) {
// 왼손으로 키패드 누르기
if(num == 1 || num == 4 || num == 7) {
answer += "L"; // 정답에 추가
dl = new int[]{r[num][0], r[num][1]}; // 왼손 위치 갱신
}
// 오른손으로 키패드 누르기
else if(num == 3 || num == 6 || num == 9) {
answer += "R";
dr = new int[]{r[num][0], r[num][1]}; // 오른손 위치 갱신
}
// 왼손인지 오른손인지 모를 경우 키패드 누르기
else {
// 거리 계산
int lDistance = Math.abs(r[num][0]-dl[0]) + Math.abs(r[num][1]-dl[1]);
int rDistance = Math.abs(r[num][0]-dr[0]) + Math.abs(r[num][1]-dr[1]);
// 거리 비교
if(lDistance > rDistance) {
// 오른손이 가까울 경우
answer += "R";
dr = new int[]{r[num][0], r[num][1]};
} else if(lDistance < rDistance) {
answer += "L";
dl = new int[]{r[num][0], r[num][1]};
} else {
// 왼손 거리 = 오른손 거리 일 경우는 왼손잡이인지, 오른손잡이인지 판별
if(hand.equals("right")) {
answer += "R";
dr = new int[]{r[num][0], r[num][1]};
} else {
answer += "L";
dl = new int[]{r[num][0], r[num][1]};
}
}
}
}
return answer;
}
}
해설 (내가 이 문제를 접근한 방법)
(1) 키패드 배열 선언 및 초기화하기
→ 여러가지 방법으로 넣을 수 있지만 자바의 배열 특성 상 해당 배열에 특정 원소가 있는지 확인하려면 일일히 순회를 해야한다. 이것을 피하기 위해 나는 키패드의 위치를 1차원 배열로 선언했다.[예: 1번 → {0, 0} 로 넣어두고 배열의 1번 인덱스에 바로 접근할 수 있게]
(2) 왼손위치, 오른손위치 저장 배열
→ 각각 저장해도 되지만 코드가 길어지는게 싫어서 그냥 배열로 선언하고 갱신해주었다
(3) numbers 배열의 원소를 for-each로 읽어가며 거리 계산 : 절댓값
비슷하게 풀어볼만한 문제
https://www.acmicpc.net/problem/20436
나는 개인적으로 위 문제가 조금 더 복잡하지만 기본적인 로직은 동일하기 때문에 풀어보면 좋을 것 같다고 느꼈다.