ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 조이스틱
    프로그래머스 알고리즘 2024. 1. 9. 15:01
    728x90

    문제

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

    조이스틱을 최소로 움직여서 알파벳을 만드는 문제이다. 

    처음 알파벳은 글자 수 * "A" 로 설정한다. (ex : "JAZ" 이면 처음 알파벳은 "AAA")

     

    먼저 내가 문제를 풀면서 처음에 생각한 방법이다.

    1. 먼저 check 배열을 통해 바꿀 알파벳을 찾는다. (A는 바꿀 필요없음)

    2. 현재 위치(index = 0)에서 가장 가까운 곳을 찾고 이동한다. (왼쪽, 오른쪽)

    3. 이동한 위치에서 상하로 알파벳을 최소로 이동하면서 바꿈(위, 아래)

     

    2 ~ 3 반복

    이에 따라 아래 코드는 내가 작성한 코드이다.

    import java.util.*;
    class Solution {
        private static int []targetAlphabet;
        private static boolean[]change;
        private static int answer;
        public int solution(String name) {
            targetAlphabet = new int[name.length()];
            change = new boolean[name.length()]; //true이면 바꿔야됨
            
            int numberOfChange = 0; //바꿔야 하는 알파벳 개수
            
            //1
            for(int i=0;i<targetAlphabet.length;i++){
                if(name.charAt(i)!='A'){
                    change[i] = true;
                    numberOfChange++; 
                }
                targetAlphabet[i] = name.charAt(i)-'A';
            }
            
            answer = 0;
            int index = 0;
    
            int temp = 0;
            for(int i=0;i<numberOfChange;i++){
                temp = index;
                index = findNearest(temp); //2
                answer += changeAlphabet(index); //3
            }
            return answer;
        }
        private static int findNearest(int idx){
            int frontIdx = idx;
            int backIdx = idx;
            
            int finalIdx = -1;
            while(true){
                if(change[frontIdx]){
                    change[frontIdx]=false;
                    finalIdx = frontIdx;
                    break;
                }
                else if(change[backIdx]){
                    change[backIdx]=false;
                    finalIdx = backIdx;
                    break;
                }
                else{
                    frontIdx++;
                    backIdx--;
                    if(frontIdx == change.length)frontIdx = 0;
                    if(backIdx < 0)backIdx = change.length-1;
                    answer++;
                }
            }
            return finalIdx;
        }
        
        private static int changeAlphabet(int idx){
            int result = 0;
            int up = Math.abs(targetAlphabet[idx]);
            int down = 26 - targetAlphabet[idx];
            result = Math.min(up, down);
            return result;
        }
    }

    하지만 몇개가 테스트케이스 일치에 실패했고, 반례를 찾았다.

    예를 들어 CCCAAAAAAY 의 경우 0번째 인덱스에서 가장 가까운 위치인 왼쪽이나 오른쪽으로 갈 수 있다.

    만약 쭉 오른쪽으로 가게 되었을 경우 CCC까지 가고 다시 뒤로 가서 Y로 가게 된다.

    C -> C -> C -> C -> C -> C -> Y

    반면에 왼쪽으로 가게 되었을 경우 Y까지 가고 다시 앞으로 가서 C로 가게 된다.

    C -> Y -> C -> C -> C

    즉, 아무리 최소 거리가 왼쪽, 오른쪽 같더라도 어느 방향을 선택함에 따라 결과가 달라지게 되는 것이다.

    이를 연속된 A 여부에 따라 조건을 걸었다.

     

     

    따라서 다시 문제의 단계를 나누었다.

    1. 알파벳을 처음부터 오른쪽 방향으로 순회

    2. 하나하나 알파벳을 상, 하 조작으로 알파벳 조작

    3. 좌, 우 조직으로 커서 위치 조작


    전체 코드이다.

    import java.util.*;
    class Solution {
        public int solution(String name) {
            int answer = 0;
            int length = name.length();
            
            int move = length-1; //오른쪽으로 쭉 이동했을 때 좌우 이동 거리
            int index; //연속된 A를 세기 위한 변수
            for(int i=0;i<length;i++){
                answer += Math.min(name.charAt(i)-'A', 'Z'- name.charAt(i)+1); //상하 이동
                
                
                index = i+1;
                while(index < length && name.charAt(index) == 'A')index++;
                
                move = Math.min(move, i*2+length-index);
                move = Math.min(move, (length-index)*2 + i);
            }
            return answer + move;
        }
    }

    '프로그래머스 알고리즘' 카테고리의 다른 글

    도둑질  (1) 2024.04.18
    디스크 컨트롤러  (0) 2024.03.21
    등산 코스 정하기  (1) 2023.11.25
    코딩 테스트 공부  (0) 2023.11.25
    표 편집  (1) 2023.11.24
Designed by Tistory.