JavaScript에서 문자열을 인자로 받아 해당 문자열에 포함된 모든 문자가 서로 중복되지 않는지 확인하는 함수를 작성해야 합니다. 문자열의 모든 문자가 고유하다면 true를 반환하고, 단 하나의 문자라도 두 번 이상 등장한다면 false를 반환해야 합니다.
접근 방식: 해시 셋(Set) 활용
이 문제는 해시 셋(Hash Set)을 사용하면 효율적으로 해결할 수 있습니다. 자바스크립트에서는 Set 객체가 이 역할을 수행합니다. 문자열을 순회하면서 각 문자를 Set에 하나씩 추가하고, 만약 이미 Set에 존재하는 문자를 다시 만나게 되면 그 즉시 false를 반환합니다. 반복이 끝날 때까지 중복이 발견되지 않았다면 모든 문자가 고유하다는 의미이므로 최종적으로 true를 반환합니다.
Set의 조회 연산은 평균적으로 O(1)의 시간 복잡도를 가지기 때문에, 전체 알고리즘의 시간 복잡도는 O(n)으로 매우 효율적입니다. 여기서 n은 문자열의 길이입니다.
코드 예제
다음은 위 로직을 구현한 코드입니다.
const str = 'abschyie';
const checkUniqueness = (str = '') => {
const hash = new Set();
for(let i = 0; i < str.length; i++){
const el = str[i];
// 이미 등장한 문자라면 중복이므로 false 반환
if(hash.has(el)){
return false;
}
hash.add(el);
}
return true;
};
console.log(checkUniqueness(str));실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.
true
예제 문자열 'abschyie'에는 중복된 문자가 없으므로 true가 출력됩니다. 만약 문자열에 같은 문자가 두 번 이상 포함되어 있다면, 예를 들어 'hello'처럼 'l'이 반복되는 경우 함수는 false를 반환합니다.
추가 팁: 더 간결한 방법
ES6의 Set 특성을 활용하면 코드를 한 줄로 줄일 수도 있습니다. Set은 중복된 값을 저장하지 않으므로, 문자열을 Set으로 변환했을 때의 크기와 원본 문자열의 길이를 비교하는 방법입니다.
const checkUniqueness = (str = '') => new Set(str).size === str.length;
두 방법 모두 시간 복잡도는 O(n)으로 동일하지만, 조기 종료(early return)가 가능한 첫 번째 방법은 중복 문자가 문자열 앞부분에 있는 경우 불필요한 순회를 줄일 수 있다는 장점이 있습니다.