공부/알고리즘

조이스틱

shining park 2025. 3. 19. 01:06

https://school.programmers.co.kr/learn/courses/30/lessons/42860

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 - 나의 코드

import java.util.*;

class Solution {
    public int solution(String name) {
        int answer = 0;
        int size = name.length();
        
        //알파벳 배열
        char[] arr = new char[26];
        for(int i=0; i<26; i++) {
            char a = 'A';
            arr[i] = (char)(a + i);
        }
        
        //기본 좌우 이동 거리 설정
        int move = size - 1;
        
        for(int i=0; i<size; i++) {
            char tmp = name.charAt(i);
            int index = 0;
            
            //알파벳 최소 조작 횟수 계산
            for(int j=0; j<26; j++) {
                if(arr[j] == tmp) {
                    if(j <= 13) {
                        index = j;
                    } else {
                        index = 26 - j;
                    }
                    break;
                }
            }
            
            answer += index;
            
            //연속된 A 구간을 찾아서 최소 좌우 이동 계산
            int next = i + 1;
            while(next < size && name.charAt(next) == 'A') {
                next++;
            }
            
            //최적 이동 거리 비교
            //처음부터 i까지 갔다가 되돌아오고(*2) + 다시 끝까지 감(size-next)
            move = Math.min(move, (i*2) + (size-next));
            //끝에서부터 시작해서((size-next)*2) + 다시 앞으로 돌아옴(+i)
            move = Math.min(move, (size-next)*2 + i);

        }
        
        answer += move;
        
        return answer;
    }
}

 

- 다른 풀이 방식

import java.util.*;

class Solution {
    public int solution(String name) {
        int answer = 0;
        int size = name.length();

        // 1️⃣ 알파벳 변경 비용 계산
        for (int i = 0; i < size; i++) {
            char tmp = name.charAt(i);
            int upDown = Math.min(tmp - 'A', 'Z' - tmp + 1); // 위/아래 최소 이동
            answer += upDown;
        }

        // 2️⃣ 좌우 이동 최소 거리 계산
        int move = size - 1; // 기본적으로 오른쪽 끝까지 가는 경우
        
        for (int i = 0; i < size; i++) {
            if (name.charAt(i) == 'A') {
                int next = i + 1;
                while (next < size && name.charAt(next) == 'A') {
                    next++; // 연속된 'A'의 끝 찾기
                }
                // 왼쪽으로 갔다가 돌아오는 경우와 비교하여 최소 이동 계산
                move = Math.min(move, (i - 1) * 2 + (size - next));
                move = Math.min(move, (size - next) * 2 + i);
            }
        }
        
        answer += move; // 좌우 이동 추가
        
        return answer;
    }
}