고정 사이즈의 윈도우가 이동하면서 윈도우 내에 있는 데이터를 이용해 문제를 풀이하는 알고리즘을 말한다.
교집합의 정보를 공유하고, 차이가 나는 양쪽 끝 원소만 갱신한다.
배열이나 리스트의 요소의 일정 범위의 값을 비교할 때 사용하면 유용하다.
1차원 배열에서 어떤 특정 조건을 만족하는 연속 구간 구할 때,
각자 다른 원소를 가리키는 2개의 포인터로 구간의 길이를 가변적으로 조작하며 조건을 충족하는 구간을 찾는 알고리즘이다.
투포인터 알고리즘 문제의 유형
투 포인트 알고리즘은 구간의 넓이가 조건에 따라 유동적으로 변하며,
슬라이딩 (윈도우) 알고리즘은 항상 구간의 넓이가 고정되어 있다는 차이점이 있다
(라고 해서 풀었는데 맞는 지 모르겠다😓)
모두 오른쪽
으로 이동하는 유형진열된 모든 종류의 보석을 적어도 1개 이상 포함하는 가장 짧은 구간을 찾아서
가장 짧은 구간의 시작 진열대 번호와 끝 진열대 번호를 차례대로 배열에 담아서 return 해야한다.
만약 가장 짧은 구간이 여러 개라면 시작 진열대 번호가 가장 작은 구간을 return 합니다.
let answer = solution([ "DIA", "RUBY", "RUBY", "DIA", "DIA" "EMERALD", "SAPPHIRE", "DIA" ]);
console.log(answer); // [3, 7]
answer = solution(["AA", "AB", "AC", "AA", "AC"]);
console.log(answer); // [1, 3]
answer = solution(["XYZ", "XYZ", "XYZ"]);
console.log(answer); // [1, 1]
answer = solution(["ZZZ", "YYY", "NNNN", "ZZZ", "BBB"]);
console.log(answer); // [1, 5]
Map 은 등록된 순서를 기억해서 순서대로 순회하는 이터러블 객체이다.
let newMap = new Map([["AA", 0], ["AB", 1]]);
console.log(newMap); // Map(2) { 'AA' => 0, 'AB' => 1 }
console.log(newMap.values()); // [Map Iterator] { 0, 1 }
// 이터레이터 객체에는 순회 결과 객체를 반환하는 next( ) 메서드가 있다.
// 순회 결과 객체에는 다음 순회 값이 있으면 그 값을 보유하는 value 프로퍼티가 있다. {value: 이터레이터 값, done: false }
console.log(newMap.values().next()); // { value: 0, done: false }
console.log(newMap.values().next().value); // 0;
// next() 메서드를 계속 호출하면 다음과 같다.
let valuesIterator = newMap.values();
let 첫번째_호출 = valuesIterator.next();
let 두번째_호출 = valuesIterator.next();
console.log(두번째_호출); // { value: 1, done: false }
let 세번째_호출 = valuesIterator.next();
console.log(세번째_호출); // { value: undefined, done: true }
function solution(gems) {
let gemsSize = new Set(gems).size;
const gemsMap = new Map();
const gemLengths = [];
gems.forEach((el, i) => {
gemsMap.delete(el);
gemsMap.set(el, i);
if (gemsMap.size === gemsSize) {
gemLengths.push([gemsMap.values().next().value + 1, i + 1]);
}
});
gemLengths.sort((a, b) => {
// 배열의 길이 같다면 시작하는 인덱스가 작은 게 앞에 오도록
if ((a[1] - a[0]) === (b[1] - b[0])) {
return a[0] - b[0];
}
// 길이가 짧은 배열이 앞에 오도록
return (a[1] - a[0]) - (b[1] - b[0]);
});
return gemLengths[0];
}
참고: 슬라이딩 윈도우 알고리즘(Sliding Window) (feat. 투 포인트)
Sliding Window
코드2 (카카오 인턴쉽 2020 : 보석 쇼핑)