Programmers(프로그래머스) 조이스틱
코딩테스트 연습 - 조이스틱
조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니다. ▲ - 다
programmers.co.kr
문제 설명
조이스틱으로 알파벳 이름을 완성하라.
처음에는 모두 A로만 이루어져 있으며, 상하로 알파벳을 선택하고, 좌우로 커서를 옮길 수 있다.
첫번째 위치에서 조이스틱을 왼쪽으로 조작하면 마지막 위치로 커서를 이동하고,
"A"에서 조이스틱을 위쪽으로 조작하면 "Z"로 입력된다.
예)
"JAZ"라는 이름을 만들기 위해, "AAA"에서 조이스틱을 다음과 같이 움직여야 한다.
- 첫번째 알파벳 "J"를 만들기 위해 조이스틱을 아래로 9번 조작 --> "JAA"
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동 --> "JAA"
- 세번째 알파벳 "Z"를 만들기 위해 조이스틱을 위로 1번 조작 --> "JAZ"
풀이
프로그래머스 문제 분류에도 나와있듯이, 탐욕법(Greedy Argorithm)으로 풀 수 있는 문제이다.
주의해야할 점은,
1) 알파벳을 조작할 때 위로 조작하는 것이 횟수가 적을지, 아래로 조작하는 것이 횟수가 적을지 판단해야 하고,
2) 알파벳을 조작한 후에는 어디로 이동해야 커서 이동을 최소화하면서 알파벳을 완성시킬 수 있을지 고민해야 한다.
2)번을 더 살펴보자면, "JBACAAAAAAZ" 같은 알파벳 이름이 주어졌을 때에 단순히 왼쪽에서 오른쪽으로 이동하면서 완성하는 것보다는, "J", "B", "C"까지 왼쪽에서 오른쪽으로 이동하면서 완성한 후, 왼쪽으로 이동해 "Z"를 찾아 완성하는 것이 더 조작 횟수가 적다는 것을 유의해야 한다는 것이다.
class Solution {
public int solution(String name) {
int answer = 0;
boolean[] arrayCompleted = new boolean[name.length()]; // 완성된 알파벳인지 체크
int cntCompleted = 0; // 완성된 알파벳 수
int index = 0; // 커서 위치
while(true)
{
// 현재 위치(index)의 알파벳 완성
int move = 0;
if(name.charAt(index) - 'A' > 13)
move = 'Z' - name.charAt(index) + 1;
else
move = name.charAt(index) - 'A';
// 알파벳 완성 여부 체크
arrayCompleted[index] = true;
cntCompleted++;
// 오른쪽으로 이동하면서 바꿀 알파벳 탐색
int right;
for(right = 1; right < name.length(); right++)
{
int nextIndex = (index + right) % name.length();
// 완성된 알파벳이라고 체크가 되어 있지 않을 때,
if(!arrayCompleted[nextIndex])
{
// 목표 알파벳이 'A'라면 조이스틱 조작 없이 완성 체크만 함
if(name.charAt(nextIndex)== 'A')
{
arrayCompleted[nextIndex] = true;
cntCompleted++;
}
// 그렇지 않은 경우 조작해야할 알파벳 찾은 것임, 탐색 종료
else
break;
}
}
// 왼쪽으로 이동하면서 바꿀 알파벳 탐색
int left;
for(left = 1; left < name.length(); left++)
{
int nextIndex = (name.length() + index - left) % name.length();
if(!arrayCompleted[nextIndex])
{
if(name.charAt(nextIndex) == 'A')
{
arrayCompleted[nextIndex] = true;
cntCompleted++;
}
else
break;
}
}
// 현재 알파벳을 완성할 때 조이스틱 조작한 횟수 누적
answer += move;
// 모두 완성 했다면 종료
if(cntCompleted >= name.length())
break;
// 바꿔야 할 알파벳들 중에서 왼쪽이 가까운 지, 오른쪽이 가까운 지 비교
if(right <= left)
{
// 바꿔야 할 알파벳으로 이동, 이동한 만큼 조이스틱 조작 횟수 누적
index = (index + right) % name.length();
answer += right;
}
else
{
index = (name.length() + index - left) % name.length();
answer += left;
}
}
return answer;
}
}
'Algorithm > Programmers' 카테고리의 다른 글
[Programmers/Level 2/Java] 라면공장 (0) | 2020.06.22 |
---|---|
[Programmers/Level 3/Java] 2 x n 타일링 (0) | 2020.06.19 |
[Programmers/Level 2/Java] 124 나라의 숫자 (0) | 2020.06.08 |
[Programmers/Level 3/Java] 종이접기 (0) | 2020.06.06 |
[Programmers/Level 2/Java] 짝지어 제거하기 (0) | 2020.06.05 |