AIL( Algorithm I Learned)

#AIL_24.01.09 // Programmers_가장 가까운 같은 글자

k0z 2024. 1. 9. 22:03

## AIL_ 가장 가까운 같은 글자

*** 문제 설명
문자열 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지문과 같습니다.
입출력 예 #2설명 생략

## solution.JavaScript

1. 문제의 접근 방식

주어진 문제 문자열에서 각 문자의 최근 등장 위치와 현재 위치의 차이를 계산하는 것입니다.


2. 문제풀이

function solution(s) {
    const answer = [];
    const last = {};

    for (let i = 0; i < s.length; i++) {
        const current = s[i];

        // 현재 문자가 이전에 등장한 적이 없으면 -1 추가
        if (!(current in last)) {
            answer.push(-1);
        } else {
            // 현재 문자의 가장 최근 등장한 위치 추가
            answer.push(i - last[current]);
        }

        // 현재 문자의 위치를 갱신
        last[current] = i;
    }

    return answer;
}
/*
테스트 1
입력값 〉	"banana"
기댓값 〉	[-1, -1, -1, 2, 2, 2]
실행 결과 〉	테스트를 통과하였습니다.
테스트 2
입력값 〉	"foobar"
기댓값 〉	[-1, -1, 1, -1, -1, -1]
실행 결과 〉	테스트를 통과하였습니다.
*/

 

1) const answer = [];: 결과를 저장할 배열 answer를 선언합니다. 이 배열에는 각 문자의 최근 등장 위치와 현재 위치의 차이가 저장됩니다.

2) const last = {};: 각 문자의 최근 등장 위치를 저장할 객체 last를 선언합니다. 이 객체는 문자를 키(key)로 가지며, 해당 문자의 최근 등장 위치를 값(value)으로 가집니다.

3) for (let i = 0; i < s.length; i++) {: 문자열 s를 순회하는 반복문입니다. i는 현재 문자의 인덱스를 나타냅니다.

4) const current = s[i];: 현재 위치의 문자를 current에 저장합니다.

5) if (!(current in last)) { answer.push(-1); } else { ... }: 현재 문자가 이전에 등장한 적이 없는 경우, 즉 current가 last 객체에 키로 존재하지 않는 경우에는 -1을 answer 배열에 추가합니다.

6) answer.push(i - last[current]);: 현재 문자가 이전에 등장한 적이 있는 경우, 현재 위치(i)와 최근 등장 위치(last[current])의 차이를 계산하여 answer 배열에 추가합니다.

7) last[current] = i;: 현재 문자의 위치를 최신으로 갱신합니다. last 객체에 현재 문자를 키로 하고 현재 위치를 값으로 저장합니다.

8) return answer;: 최종적으로 구해진 결과 배열 answer를 반환합니다.


3. 다른사람의 문제풀이 및 접근방식 분석

function solution(s) {
    const hash={};

    return [...s].map((v,i)=>{
        let result = hash[v] !== undefined ? i - hash[v] : -1;
        hash[v] = i;
        return result;
    });
}
/*
테스트 1
입력값 〉	"banana"
기댓값 〉	[-1, -1, -1, 2, 2, 2]
실행 결과 〉	테스트를 통과하였습니다.
테스트 2
입력값 〉	"foobar"
기댓값 〉	[-1, -1, 1, -1, -1, -1]
실행 결과 〉	테스트를 통과하였습니다.
*/

 

 

1) const hash={};: 문자의 최근 등장 위치를 저장할 객체 hash를 선언합니다.

 

2) return [...s].map((v,i) => { ... });: 문자열 s를 배열로 변환하고, 각 문자(v)와 해당 문자의 인덱스(i)에 대해 map 함수를 사용합니다. 이 부분은 문자열을 순회하면서 각 문자에 대한 처리를 수행합니다.

 

3) let result = hash[v] !== undefined ? i - hash[v] : -1;: 현재 문자 v의 최근 등장 위치가 정의되어 있다면 현재 위치(i)와 최근 등장 위치(hash[v])의 차이를 계산하고, 그렇지 않은 경우 -1을 할당합니다. 이 값은 각 문자에 대한 최근 등장 위치와 현재 위치의 차이를 나타냅니다.

 

4) hash[v] = i;: 현재 문자 v의 위치를 최신으로 갱신합니다. hash 객체에 현재 문자를 키로 하고 현재 위치를 값으로 저장합니다.

 

5) return result;: 각 문자에 대한 최근 등장 위치와 현재 위치의 차이를 담은 result 값을 배열로 반환합니다.