나는 못풀었던, 어려운 알고리즘 문제중 하나. 기억에 남기에 남겨본다.
* 문제
String 형인 str 인자에서 중복되지 않은 알파벳으로 이루어진 제일 긴 단어의 길이를 반환해주세요.
str: 텍스트
return: 중복되지 않은 알파벳 길이 (숫자 반환)
예를 들어,
str = "abcabcabc"
return은 3
=> 'abc' 가 제일 길기 때문
str = "aaaaa"
return은 1
=> 'a' 가 제일 길기 때문
str = "sttrg"
return은 3
=> 'trg' 가 제일 길기 때문
많은 생각을 요했던 알고리즘 문제 였던 것 같다. 한가지 테스트는 끝까지 통과하지 못했다.
위의 로직을 코드로 풀면 아래와 같다.
const getLengthOfStr = str => {
let toArry = str.split("");
let newArry = [];
let newLength = [];
if (toArry.length !== 0) {
// 최초 값 대입
newArry.push(toArry[0]);
newLength.push(1);
//중복 문자 체크
for (let i = 1; i < toArry.length; i++) {
if ((i === (toArry.length-1)) && (!newArry.includes(toArry[i]))) {
newArry.push(toArry[i]);
newLength.push(newArry.length);
} else if (newArry.includes(toArry[i])) {
newLength.push(newArry.length);
newArry = [];
newArry.push(toArry[i]);
} else if (!newArry.includes(toArry[i])) {
newArry.push(toArry[i]);
}
}
const max = Math.max(...newLength);
return max;
} else {
return 0;
}
}
나의 풀이는 abcabcd
와 같은 단순한(?) 문자열에서는 문제없이 작동한다. 하지만, abcdefcighzh
와 같은 문자에서는 작동하지 않는다. 왜냐하면, 두번째 c에서 중복을 확인한 후, 다음 문자인 i에 대해서 중복문자 체크를 하기 때문. i가 아닌 앞쪽의 d로 이동하여 중복문자 체크를 재시작 하여야 한다. 내 풀이는 중복문자를 찾았을 때, 첫번째 문자로 이동하여 그 다음 문자부터 다시 체크를 시작하도록 하는 장치가 없었다.
function getLengthOfStr(s) {
let strArr = [];
let prevStrArr = [];
for (let i = 0; i < s.length; i++) {
let ss = s.slice(i, i+1);
for (let j = 0; j < strArr.length; j++) {
if (ss === strArr[j]) {
if (prevStrArr.length < strArr.length) {
prevStrArr = strArr.slice();
}
strArr = strArr.splice(j+1, strArr.length);
break;
}
}
strArr.push(ss);
}
return Math.max(strArr.length, prevStrArr.length);
}
모범 풀이의 접근은 아래와 같다.
세상은 넓고 뛰어난 알고리즘 풀이는 어디나 존재한다. ^-^