Programmers 42860. 조이스틱
Title
Programmers 42860. 조이스틱
Category
AlgorithmTags
Aliases
Programmers 42860. 조이스틱Created
3 years ago
Updated
last year
| 문제 유형 | 난이도 | 걸린 시간 | 해결 유무(✅/❌) |
|---|---|---|---|
| 탐욕법(그리디) | lv.2 | 1시간 30분 | ✅ |
설계 방법
A가 아닌 위치(방문해야할 위치)의 index 들을 Map 자료구조에 담는다.
positions반복문
방문할 위치의 최소 알파벳 이동 거리를 구해서
move에 더한다. (range 함수를만들어 썼는데, 다시보니 불필요한 코드인 듯)현재 위치를 방문한 것으로 처리.
positions.delete방문할 위치가 남아있지 않으면 반복문 종료
positions를 순회하며 최단 거리로 이동할 수 있는 위치를 찾는다.해당 위치로 이동하고 이동한 만큼
move에 더한다.
코드
javascript
function solution(name) {
const dirties = [...name].map((ch) => ch !== 'A');
const positions = dirties.reduce(
(map, cur, i) => (cur ? new Map([...map, [i, i]]) : map),
new Map(),
);
const length = name.length;
let curPosition = 0;
let move = 0;
while (true) {
move += findLeastAlphabetMove(name[curPosition]);
positions.delete(curPosition);
if (!positions.size) {
break;
}
let leastDistance = length;
let nextPosition = curPosition;
positions.forEach((position) => {
const distance = Math.min(
Math.abs(curPosition + length - position),
Math.abs(position - curPosition),
);
if (distance < leastDistance) {
leastDistance = distance;
nextPosition = position;
}
});
curPosition = nextPosition;
move += leastDistance;
}
return move;
}
const range = (start, stop, step) =>
Array.from({length: (stop - start) / step + 1}, (_, i) => start + i * step);
const findLeastAlphabetMove = (target) => {
const alphabets = new Map(
range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1)
.map((x) => String.fromCharCode(x))
.map((v, i) => [v, i]),
);
const targetPosition = alphabets.get(target);
return alphabets.size / 2 > targetPosition
? targetPosition
: alphabets.size - targetPosition;
};
function solution(name) {
const dirties = [...name].map((ch) => ch !== 'A');
const positions = dirties.reduce(
(map, cur, i) => (cur ? new Map([...map, [i, i]]) : map),
new Map(),
);
const length = name.length;
let curPosition = 0;
let move = 0;
while (true) {
move += findLeastAlphabetMove(name[curPosition]);
positions.delete(curPosition);
if (!positions.size) {
break;
}
let leastDistance = length;
let nextPosition = curPosition;
positions.forEach((position) => {
const distance = Math.min(
Math.abs(curPosition + length - position),
Math.abs(position - curPosition),
);
if (distance < leastDistance) {
leastDistance = distance;
nextPosition = position;
}
});
curPosition = nextPosition;
move += leastDistance;
}
return move;
}
const range = (start, stop, step) =>
Array.from({length: (stop - start) / step + 1}, (_, i) => start + i * step);
const findLeastAlphabetMove = (target) => {
const alphabets = new Map(
range('A'.charCodeAt(0), 'Z'.charCodeAt(0), 1)
.map((x) => String.fromCharCode(x))
.map((v, i) => [v, i]),
);
const targetPosition = alphabets.get(target);
return alphabets.size / 2 > targetPosition
? targetPosition
: alphabets.size - targetPosition;
};
시간 복잡도
A가 아닌 위치 개수 (N)
O(N!)
어려웠던 점
그리디 알고리즘을 아직 잘 모르겠다..
다른 풀이를 보니 오른쪽으로만 가는 경우, 왼쪽으로만 가는 경우, 오른쪽으로 갔다가 왼쪽으로 가는 경우, 왼쪽으로 갔다가 오른쪽으로 가는 경우로 나누어서 풀었는데, 이 풀이를 떠올리기는 어려웠다.
Younho9 Notes