Lv 2. 조이스틱

2025. 2. 5. 19:24·Algorithm & Data Structures/Programers

 

https://school.programmers.co.kr/learn/courses/30/lessons/42860?language=java

 

프로그래머스

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

programmers.co.kr

 

 

 

🔠 자바(Java)로 푸는 조이스틱 문제 풀이

🔎 문제 개요

이 문제는 프로그래머스의 "조이스틱" 문제입니다.
주어진 문자열을 "A"로 초기화된 상태에서 목표 문자열로 변경하기 위한 최소 조작 횟수를 구하는 문제입니다.

💡 예제 입력

String name = "JAZ";

💡 예제 출력

11

위 예제에서 JAZ로 만들기 위해 최소 조작 횟수는 11입니다.


🛠 알고리즘 접근 방식

이 문제를 해결하기 위해 문자 변경 비용과 커서 이동 비용을 최소화해야 합니다.

✏️ 주요 고려 사항

  1. 알파벳 변경 비용
    • 각 문자를 변경할 때 A에서 해당 문자까지 이동하는 비용을 계산해야 합니다.
    • 알파벳은 'A'부터 'Z'까지 26개 존재하며, 위쪽 이동(+)과 아래쪽 이동(-) 중 최단 거리를 선택해야 합니다.
    • 예를 들어 'B'는 A → B (+1)이지만, 'Z'는 A → Z (-1)로 이동하는 것이 더 짧습니다.
    • 이를 일반화하면:
      변경 비용 = min(문자 - 'A', 'Z' - 문자 + 1)
      
  2. 커서 이동 비용
    • 문자열의 각 문자를 변경해야 하므로 좌우 이동 비용을 고려해야 합니다.
    • 초기 커서 위치는 0이며, 왼쪽 또는 오른쪽 방향으로 이동하여 최적의 경로를 찾아야 합니다.
    • 연속된 A가 많을 경우, 단순히 끝까지 가는 것보다 중간에 방향을 바꾸는 것이 더 효율적일 수도 있음.

🔹 Java 코드 해설

import java.util.*;

class Solution {
    int calculate(char c) {
        return Math.min(c - 'A', 'Z' - c + 1);  // 알파벳 변경 최소 비용 계산
    }

    public int solution(String name) {
        int answer = 0;
        int size = name.length();
        int move = size - 1;  // 기본적으로 왼쪽에서 오른쪽으로 끝까지 가는 경우

        for (int i = 0; i < size; i++) {
            char c = name.charAt(i);
            answer += calculate(c);  // 문자 변경 비용 추가

            // 연속된 'A'를 고려한 커서 최소 이동 거리 계산
            if (i < size - 1 && name.charAt(i + 1) == 'A') {
                int endA = i + 1;
                while (endA < size && name.charAt(endA) == 'A') {
                    endA++;  // 연속된 'A'의 마지막 인덱스 찾기
                }

                // 커서를 되돌아가는 경우와 끝까지 가는 경우 중 최솟값 선택
                move = Math.min(move, i * 2 + (size - endA));
                move = Math.min(move, i + (size - endA) * 2);
            }
        }

        return answer + move;  // 문자 변경 횟수 + 최소 이동 횟수 반환
    }
}

🔍 코드 설명

📌 1. 알파벳 변경 비용 계산 (calculate())

int calculate(char c) {
    return Math.min(c - 'A', 'Z' - c + 1);
}
  • 'A'에서 목표 문자까지 이동하는 최소 횟수를 반환하는 함수입니다.
  • c - 'A' : 'A'부터 c까지 증가하는 거리
  • 'Z' - c + 1 : 'Z'에서 c로 감소하는 거리

예제)

  • 'B' → min(1, 25) = 1
  • 'Z' → min(25, 1) = 1
  • 'J' → min(9, 17) = 9

📌 2. 커서 이동 계산 (solution())

int move = size - 1;  // 기본적으로 오른쪽 끝까지 이동하는 경우
  • 처음에는 커서를 단순히 오른쪽 끝까지 이동한다고 가정합니다.
if (i < size - 1 && name.charAt(i + 1) == 'A') {
    int endA = i + 1;
    while (endA < size && name.charAt(endA) == 'A') {
        endA++;  // 연속된 'A'의 마지막 인덱스 찾기
    }

    move = Math.min(move, i * 2 + (size - endA));
    move = Math.min(move, i + (size - endA) * 2);
}
  • 연속된 'A'가 있는 경우, 방향을 바꿔 이동하는 것이 더 효율적일 수도 있음
    1. i * 2 + (size - endA) → 앞쪽에서 되돌아간 후 끝까지 가는 경우
    2. i + (size - endA) * 2 → 먼저 끝까지 간 후 되돌아오는 경우
  • move 값을 갱신하여 최소 이동 거리로 업데이트합니다.

🔥 시간 복잡도 분석

연산 최악의 경우 수행 횟수 시간 복잡도
calculate() 호출 N O(N)
for 루프 N O(N)
while 루프 (연속된 'A' 탐색) N O(N)
총합 O(N)  

📌 결론
👉 모든 연산이 O(N) 이내로 수행되므로 효율적입니다.


🏆 정리

✅ 핵심 포인트

  1. 알파벳 변경 최소 비용을 계산한다.
  2. 좌우 이동을 최소화하기 위해 최적의 경로를 찾는다.
    • 연속된 'A' 구간을 피하기 위해 되돌아가는 경우와 직진하는 경우를 비교한다.
  3. 시간 복잡도 O(N)으로 최적화한다.

🎯 이 알고리즘의 장점

✔ 불필요한 연산을 줄이고 최적의 이동 경로를 탐색
✔ O(N)으로 해결 가능하여 성능이 우수함
✔ 조이스틱 조작 횟수를 최소화하는 최적의 방법 제공

이제 이 방법을 적용하면 조이스틱 문제를 빠르게 해결할 수 있습니다!
💡 효율적인 탐색 기법을 익혀두면, 유사한 문제에서도 유용하게 사용할 수 있습니다. 🚀


이 글이 도움이 되었다면, 좋아요와 공유 부탁드립니다! 😊

 

 

 

'Algorithm & Data Structures > Programers' 카테고리의 다른 글

Lv 3. 기둥과 보  (0) 2025.03.03
Lv 2. 양궁대회  (0) 2025.02.28
Lv 2. 숫자블록  (0) 2025.02.03
Lv3. 길찾기 게임  (1) 2025.01.24
Lv2. 혼자 놀기의 달인  (0) 2025.01.22
'Algorithm & Data Structures/Programers' 카테고리의 다른 글
  • Lv 3. 기둥과 보
  • Lv 2. 양궁대회
  • Lv 2. 숫자블록
  • Lv3. 길찾기 게임
Geisha
Geisha
개발 일기
  • Geisha
    Geisha
    Geisha
  • 전체
    오늘
    어제
    • 분류 전체보기 (311) N
      • Algorithm & Data Structures (235) N
        • BOJ (93) N
        • SWEA (1)
        • Programers (137) N
        • Data Structures (3)
      • DB (23) N
        • SQL (17) N
        • RDBMS (2)
      • Java (1)
        • Class (1)
      • Spring (5)
        • Spring MVC (1)
        • Annotations (1)
      • CS (36)
        • 운영체제 (13)
        • 네트워크 (5)
      • Tool (6)
        • Git (5)
        • AWS (1)
      • Project (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    algorithm
    프로그래머스
    동적계획법
    Dijkstra
    후위순회
    골드
    전위순회
    알고리즘
    투포인터
    BFS
    unionfind
    구현
    유니온파인드
    스택
    백트래킹
    DynamicProgramming
    경로압축
    SQL
    Java
    PriorityQueue
    Stack
    백준
    이분탐색
    다익스트라
    Union-Find
    binarySearch
    dp
    dfs
    baekjoon
    programmers
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Geisha
Lv 2. 조이스틱
상단으로

티스토리툴바