[Programmers / Level2] 조이스틱(Java)

이하얀·2024년 4월 17일
0

💡 Info



입출력 조건



입출력 예시



문제 이해

  • 만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 리턴
    • 상하좌우로 이동하는 횟수를 계산
      • 상하의 경우 : 알파벳(A to Z) 순서대로 -> A부터 Z까지의 총 26개의 알파벳에 번호를 매겨 파악

        • 알파벳을 🔼 조작한다면 뒤 알파벳 - 앞 알파벳으로 계산, 알파벳을 🔽 조작한다면 총 알파벳 수(26) - 뒤 알파벳 - 앞 알파벳으로 계산하여 두 수를 Math.min으로 비교

      • 좌우의 경우 : 커서 조작

        • ▶️, ◀️ 이동의 경우 name.length() - 1까지의 길이에서
          • 연속된 A 횟수를 기준으로 연속된 A 앞보다 뒷부분이 짧다면 뒤로 이동해서 조작(=맨 마지막에서 다시 맨 앞으로 오는 조작)하는 것이 더 유리!


예시로 이해하기 : ZYXAAAAAB

📍 출처 : [프로그래머스] 조이스틱_JAVA

  • ZYXAAAAAB
    • 현재 위치 = X, index = 2, 연속된 A가 끝나는 지점 = 8

1️⃣ ZYXYZB 순으로 이동하는 경우

  • 0에서 시작
  • X가 있는 2[X]까지 이동
  • 다시 0으로 돌아가기
  • 한번 더 왼쪽으로 움직여 B로 이동
  • "0에서 시작 -> X가 있는 2[X]까지 이동 -> 다시 0으로 돌아가기"까지 = i(현재 위치 X를 뜻함) * 2
  • "한번 더 왼쪽으로 움직여 B로 이동" = 'A'가 연속해서 나오는 부분을 지나고 남은 거리 = (name.length() - 연속된 A가 끝나는 지점)

2️⃣ ZBZYX 순으로 이동하는 경우

  • 0에서 시작
  • 왼쪽으로 이동
  • 다시 0으로 돌아가기
  • 오른쪽으로 이동
  • (name.length() - 연속된 A가 끝나는 지점) * 2 + i


💭 알고리즘

풀이 시간 : 45분

  1. answer(조작 횟수) 변수 선언하기

  2. 값 확인 및 이동 횟수 변수 선언하기

  3. 상하로 움직이는 경우 계산하기

    • Math.min(알파벳2 - 알파벳1 , 26 - (알파벳2 - 알파벳1))
  4. 좌우로 움직이는 경우 계산하기

    • 오른쪽으로 갔다 다시 왼쪽으로 꺾기
      • move = Math.min(원래 이동 횟수, 뒤로 돌아가 계산하는 횟수)
    • 왼쪽으로 갔다 다시 오른쪽으로 꺾기
      • move = Math.min(move, 뒤로 돌아가 계산하는 횟수)
  5. answer는 상하, move는 좌우에 해당하므로 두 값 더해 최종 값 출력하기

import java.util.*;

class Solution {
    public int solution(String name) {
        
    // 1. answer(조작 횟수) 변수 선언하기
    int answer = 0;
    
    // 2. 값 확인 및 이동 횟수 변수 선언하기
    int index;
    int move = name.length() - 1; // 오른쪽을 기준으로 계속 오른쪽으로 이동하는 횟수
    
    /* 3. 상하로 움직이는 경우 계산하기
    - Math.min(알파벳2 - 알파벳1 , 26 - (알파벳2 - 알파벳1)) */
    for(int i=0; i<name.length(); i++){
        answer += Math.min(name.charAt(i) - 'A', 26 - (name.charAt(i) - 'A'));
        
        index = i + 1; //다음 위치
        while(index < name.length() && name.charAt(index) == 'A'){
            index++;
        }
        
        // 4. 좌우로 움직이는 경우 계산하기
        /* - 오른쪽으로 갔다 다시 왼쪽으로 꺾기
             - move = Math.min(원래 이동 횟수, 뒤로 돌아가 계산하는 횟수) */
        move = Math.min(move, i*2 + (name.length() - index));
        
        /* - 왼쪽으로 갔다 다시 오른쪽으로 꺾기
             - move = Math.min(move, 뒤로 돌아가 계산하는 횟수) */
        move = Math.min(move, (name.length() - index) * 2 + i);
    }
        return answer + move; //answer는 상하, move는 좌우에 해당하므로 두 값 더하기
    }
}


💭 결과

profile
언젠가 내 코드로 세상에 기여할 수 있도록, BE 개발 기록 노트☘️

0개의 댓글