반응형
문제
조이스틱
https://school.programmers.co.kr/learn/courses/30/lessons/42860
풀이
설명
조이스틱 조작 횟수의 최솟값을 구하는 문제입니다.
조작 횟수는 수직 이동 횟수 + 수평 이동 횟수입니다.
수직 이동 횟수는 문자열을 순회하며 각 문자가 기본 문자와 얼마나 차이나는지를 구하면 됩니다.
신경써야 할 부분은 수평 이동 횟수인데요.
수평으로 이동하는 시나리오는 총 두 가지입니다.
- 한 쪽 방향으로 쭉 이동할 경우
- 한 쪽 방향으로 이동하다가 특정 지점에서 반대쪽 방향으로 이동할 경우
2번을 고려하기 위해서, 기본 문자인 A가 아니면서 가까운 두 문자의 인덱스 i와 j를 찾아 첫 문자에서 i까지 오른쪽으로 이동한 횟수와 j까지 왼쪽으로 이동한 횟수를 구해야 합니다.
둘 중 더 작은 구간을 먼저 다녀오고, 이후 더 큰 구간을 가야 값이 더 작아집니다. 따라서 작은 구간 길이 * 2 + 큰 구간 길이를 구해 지금까지 구한 최소 횟수와 비교하면 됩니다.
아래는 이름이 "ABABAAAAAAAABA"일 때, 수평 이동 횟수의 최솟값입니다.
예시 코드
function solution(name) {
const DEFAULT_CHARACTER = "A";
const LAST_ALPHABET = "Z";
const length = name.length;
let verticalMoves = 0;
// 1. 수직 이동 횟수 계산
for (const char of name) {
verticalMoves += Math.min(
char.charCodeAt(0) - DEFAULT_CHARACTER.charCodeAt(0),
LAST_ALPHABET.charCodeAt(0) - char.charCodeAt(0) + 1
);
}
// 2. 수평 이동 횟수 계산
let horizontalMoves = length - 1;
for (let i = 1; i < length; i++) {
if (name[i] !== DEFAULT_CHARACTER) continue;
let j = i + 1;
while (j < length && name[j] === DEFAULT_CHARACTER) {
j++;
}
const rightMoves = i - 1;
const leftMoves = length - j;
const smallerMoves = Math.min(rightMoves, leftMoves);
const largerMoves = Math.max(rightMoves, leftMoves);
horizontalMoves = Math.min(horizontalMoves, smallerMoves * 2 + largerMoves);
i = j; // 연속된 A 구간 건너뛰기
}
return verticalMoves + horizontalMoves;
}
현재 코드는 수평 이동 시나리오 1번과 2번을 한 번에 계산하고 있습니다.
또한 불필요한 반복을 줄이기 위해 i가 "A"가 아닌 문자 바로 다음 인덱스를 가리키고 있습니다.
'Coding Problem' 카테고리의 다른 글
[프로그래머스] PCCP - 동영상 재생기 (0) | 2024.12.19 |
---|---|
[프로그래머스] 카카오 - 양과 늑대 (0) | 2024.12.18 |
[프로그래머스] 숫자 블록 (0) | 2024.12.15 |
[프로그래머스] 카카오 - 압축 (0) | 2024.12.13 |
[프로그래머스] 배달 (0) | 2024.12.12 |