문자열을 입력받아 다음의 조건을 만족하는 LPS*를 찾아 그 길이를 리턴해야 합니다.
- LPS: 주어진 문자열의 가장 긴 접두어이자 접미어(Longest Prefix which is also Suffix)
- non-overlapping: 접두어와 접미어는 서로 겹치는 부분이 없어야 합니다. 다시 말해, prefix와 suffix는 문자열의 동일한 인덱스에 위치한 문자를 요소로 가지면 안 됩니다.
입력
인자 1 : str
- string 타입의 임의의 알파벳 소문자 문자열 (
- str.length는 60,000 이하
출력
- number 타입을 리턴해야 합니다.
주의사항
- prefix(접두어)는 문자열의 첫 인덱스부터 시작하는 모든 부분 문자열을 의미합니다.
- suffix(접미어)는 문자열의 마지막 인덱스부터 시작하는 모든 부분 문자열을 의미합니다.
입출력 예시
let output = LPS('abbbcc');
console.log(output); // --> 0
output = LPS('aaaa');
console.log(output); // --> 2
// prefix: str.slice(0, 2)
// suffix: str.slice(2)
// non-overlapping 조건이 없는 경우 정답은 4 입니다.
output = LPS('aaaaa');
console.log(output); // --> 2
// prefix: str.slice(0, 2)
// suffix: str.slice(3)
// non-overlapping 조건이 없는 경우 정답은 5 입니다.
Advanced
- LPS를 계산하는 효율적인 알고리즘(O(N))이 존재합니다. 쉽지 않기 때문에 바로 레퍼런스 코드를 보고 이해하는 데 집중하시기 바랍니다.
- 정규식(regular expression)을 활용하면 아래처럼 간단하게 구현할 수 있습니다. 정규식에 대해서 학습하시기 바랍니다. (참고사이트)
const LPS = (str) => {
const result = str.match(/^(\w*).*\1$/);
return result[1].length;
};
문제 이해
주어진 문자열에서 가장 긴 접두어이자 접미어를 찾아야 하는데, 이때 접두어와 접미어가 겹쳐선 안됩니다.
즉, 문자열의 가운데를 기준으로 접두어와 접미어로 나뉘어야 합니다.
헷갈릴 수 있는게 대칭과는 다른 의미인데 예시로 설명해 보겠습니다.
1. 주어진 문자열이 겹치지 않는 접두어와 접미어일 경우: ABCDABC
2. 주어진 문자열이 가운데를 기준으로 대칭인 경우: ABCDCBA
1번처럼 D를 중심으로 접두어와 접미어가 각각 ABC인 문자열 인지를 판별해야 합니다.
풀이 💡
const LPS = function (str) {
let arr = str.split("");
let count = 0;
for (let i = 0; i < parseInt(arr.length / 2); i++) {
if (
arr.slice(0, i + 1).toString() ==
arr.slice(arr.length - 1 - i, arr.length).toString()
) {
count=i+1;
}
}
return count;
};
문자열을 탐색하기 위해서는 for문을 사용해야 하고 그러기 위해서 배열로 만들어 주고
count라는 변수를 선언하여 가장 길 때의 접두(미)어를 담아 for문이 종료된 후 리턴해야 합니다.
let arr = str.split("");
let count = 0;
문자열의 앞부분과 뒷부분만 비교하면 되므로 길이의 절반만큼(parseInt(arr.length/2))만 for문을 실행합니다.
arr.slice(0, i + 1) 가 어려울 수 있는데 문자열의 접두어를 한 글자씩 늘려간다는 의미입니다.
ABCDABC를 예시로 들면
i=0 일 때, A
i=1 일 때, AB
i=2 일 때, ABC
arr.slice(arr.length - 1 - i, arr.length) 는 접미어에 해당하는 부분으로 거꾸로 한 글자씩 늘려 간다는 의미입니다.
ABCDABC를 예시로 들면
i=0 일 때, C
i=1 일 때, BC
i=2 일 때, ABC
i가 0,1일 때에는 다르고 2일 때 같으므로 count는 3이 됩니다.
for (let i = 0; i < parseInt(arr.length / 2); i++) {
if (
arr.slice(0, i + 1).toString() ==
arr.slice(arr.length - 1 - i, arr.length).toString()
) {
count=i+1;
}
}
더 좋은 풀이법이나 궁금한 점이 있으시면 댓글 부탁드립니다. 감사합니다.
'프로그래밍 > 코딩 테스트' 카테고리의 다른 글
[코테] 옹알이 (1) Lv. 0 (32%) (0) | 2023.08.27 |
---|---|
[코테] 정수를 나선형으로 배치하기 Lv. 0 (45%) (0) | 2023.08.27 |
[코테 js] treeBFS 너비 우선 탐색(BFS, Breadth First Search) (0) | 2023.01.18 |
[코테] 멱집합(Power set) (0) | 2023.01.16 |
[코테 js] treeDFS 깊이 우선 탐색 문제 (0) | 2023.01.09 |
댓글