[프로그래머스] 가장 가까운 같은 글자 (Javascript)
문제
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
요구사항
문자열 s가 주어졌을 때, s의 각 위치마다 자신보다 앞에 나왔으면서, 자신과 가장 가까운 곳에 있는 같은 글자가 어디 있는지 알고 싶습니다. 예를 들어, s="banana"라고 할 때, 각 글자들을 왼쪽부터 오른쪽으로 읽어 나가면서 다음과 같이 진행할 수 있습니다.
b는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
a는 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
n은 처음 나왔기 때문에 자신의 앞에 같은 글자가 없습니다. 이는 -1로 표현합니다.
a는 자신보다 두 칸 앞에 a가 있습니다. 이는 2로 표현합니다.
n도 자신보다 두 칸 앞에 n이 있습니다. 이는 2로 표현합니다.
a는 자신보다 두 칸, 네 칸 앞에 a가 있습니다. 이 중 가까운 것은 두 칸 앞이고, 이는 2로 표현합니다.
따라서 최종 결과물은 [-1, -1, -1, 2, 2, 2]가 됩니다.
문자열 s이 주어질 때, 위와 같이 정의된 연산을 수행하는 함수 solution을 완성해주세요.
제한조건
1 ≤ s의 길이 ≤ 10,000
- s은 영어 소문자로만 이루어져 있습니다.
입출력
s result "banana" [-1, -1, -1, 2, 2, 2] "foobar" [-1, -1, 1, -1, -1, -1]
내가 생각한 로직
1. 문자열을 배열로 만들어서 map 메서드를 사용한다.
2. 문자의 인덱스(map 안의 문자)와 문자열에서 해당 문자의 인덱스가 동일하다면 -1을 반환한다.
3. 문자의 인덱스와 문자열에서 해당 문자의 인덱스가 동일하지 않다면, 문자의 인덱스에서 해당 최근에 나왔던 똑같은 문자의 인덱스를 뺀다.
🚨 막혔던 부분
3번을 코드로 구현하는데 시간이 걸렸다.
인덱스를 찾는 메서드에는 indexOf와 lastIndexOf가 있다.
이걸로 해당 문자가 맨 처음 나올 때의 인덱스와 맨 마지막에 나올 때의 인덱스를 구할 수 있지만,
중간에 나온 문자의 인덱스를 구할 수는 없었다.
중간에 나온 문자의 인덱스를 어떻게 저장할 수 있을까에 대한 고민을 오랫동안 하였다.
1시간이 거의 다 되어가서 GPT에게 힌트를 달라고 요청하였다.
✅ 객체를 통해 인덱스 위치를 저장해보는 방법을 힌트로 주었다.
이 방법을 통해 무사히 코드를 구현할 수 있었다.
내가 구현한 코드
💻 전체 코드
function solution(s) {
const obj = {};
return s.split("").map((char,idx) => {
if (s.indexOf(char) === idx) return -1
if (s.indexOf(char) !== idx) {
const result = obj[char] ? idx - obj[char] : idx - s.indexOf(char)
obj[char] = idx;
return result;
}
});
}
s.split("").map()
반환해야 되는 값이 배열이었기 때문에
문자열을 미리 배열로 만들어주면 좋을 것 같았다.
split("")를 이용해서 문자열 하나하나가 담긴 배열을 만들었다.
map을 이용해서 새로운 배열을 반환하는 것을 생각하였다.
if (s.indexOf(char) === idx) return -1
맨 처음에 나온 문자라면 지금 문자의 인덱스와 문자열에서의 인덱스가 동일할 것이다.
if를 통해 조건식을 작성하였다.
if (s.indexOf(char) !== idx) {
const result = obj[char] ? idx - obj[char] : idx - s.indexOf(char);
obj[char] = idx;
return result;
}
객체 안에 해당 문자가 들어있지 않다면, 앞쪽에 있던 문자의 위치가 저장되어 있지 않다는 소리이다.
그럴 때에는 해당 문자의 인덱스에서 문자열 내에서의 인덱스를 빼준다.
객체 안에 해당 문자가 들어있다는 것은 앞쪽에 있던 문자의 위치가 저장되어 있다는 소리이다.
해당 문자의 인덱스에서 객체에 저장되어 있는 문자열 내의 인덱스를 빼주면 된다.
다른 해결방법
사용한 도구: spead operator, map, slice, lastIndexOf
const solution = (s) =>
[...s].map((char, i) => {
const count = s.slice(0, i).lastIndexOf(char);
return count < 0 ? count : i - count;
});
이 코드에서는 spread operator을 이용해서 배열을 만들었다.