[ココア実習生]宝石ショッピング


質問する


https://programmers.co.kr/learn/courses/30/lessons/67258
初めて二重ポインタの問題をするので、理解しにくいです.
普段はJavaScript文法を最大限に利用するのが好きですが、アルゴリズムを学ぶときに理解しないことが多いので、基本的な文法を使いました.
問題を簡単に説明する.

問題は、少なくとも1つ以上のすべてのタイプの宝石を含む最短区間を見つけ、開始インデックスと終了インデックスを返すことです.
このため,宝石入りmapを発表し,二重ポインタアルゴリズムを用いるために左右変数を発表した.そして総宝石の数も得られた.
    let len = new Set(gems).size;
    let map = new Map().set(gems[0],1);
    let left = 0, right = 0;
次にwhileゲートの周りでアルゴリズムを実行します.
	if(map.size < len){ // 보석이 다 안들어감
            right++; 	// right 를 증가시킨다.
            if(map.has(gems[right])){
                map.set(gems[right], map.get(gems[right])+1);
            }else {
                map.set(gems[right], 1);
            }
        }
区間内に存在する宝石の数をmapの大きさと決定した場合.左と右の間の区間に宝石がすべてない場合は、右を加えて区間を拡大します.
	else {  
            if(map.get(gems[left]) === 1){
                map.delete(gems[left]); 
            }else {
                map.set(gems[left], map.get(gems[left])-1);
            }
            left++;
        }
区間内にすべての宝石が存在する場合は、左側を増やしたり、他の区間を確認したりすることができます.
     if(map.size === len && right - left < answer[1] - answer[0]){
            answer = [left+1, right+1];
        }
すべての宝石を持つ最短区間を見つけて答えに入れます.

最終コード

function solution(gems) {
    var answer = [1, gems.length];
    let len = new Set(gems).size;
    let map = new Map().set(gems[0],1);
    let left = 0, right = 0;
    
    while(right < gems.length){
        
        if(map.size === len && right - left < answer[1] - answer[0]){
            answer = [left+1, right+1];
        } // 모든 보석을 포함하고, 가장 짧은 구간
        
        if(map.size < len){ 
            right++; 
            if(map.has(gems[right])){
                map.set(gems[right], map.get(gems[right])+1);
            }else {
                map.set(gems[right], 1);
            }
        } else {  
            if(map.get(gems[left]) === 1){
                map.delete(gems[left]); 
            }else {
                map.set(gems[left], map.get(gems[left])-1);
            }
            left++;
        }
    }
    return answer;
}