
-> 최적화 문제이기에 가장 먼저 투포인터, 슬라이딩 윈도우를 생각해봄.
-> 투포인터 알고리즘을 사용하여, 모든 종류의 보석이 담길때까지 오른쪽 포인터를 늘리다가.
-> 모든 종류의 보석이 담기게 되면, 최소 길이 구간을 찾기 위해 좌측 포인터를 늘린다.
좌측 포인터 - 우측 포인터 까지를 Array로
좌측 포인터 - 우측 포인터 까지를 Map으로
좌측 포인터 - 우측 포인터 까지를 Set으로
여러 가지 자료구조로 도전해보았는데, 배열의 경우 시간초과가 발생한다. 이차 시간이됨.
Set으로 구현하게 되면, 중복이 제거되는 특징 때문에, 몇개가 포함된 것인지를 따로 저장해주어야한다.
Map(객체)으로 구현 결정하였다.
function solution(gems) {
    let answer = []
    let jewels = {}
    gems.forEach((i)=>{
        jewels[i] = true;
    })
    
    jewels = Object.keys(jewels);
    
    let left = 0;
    
    let right = 0;
    
    let min = 100000000;
    
    const map = new Map();
    
    while( left <= right && right<=gems.length){
        
        if(map.size === jewels.length){
          // 5개가 되었으므로 좌측을 늘린다.  
          
          	const key = gems[left];
            
            answer.push([left,right-1,right-1-left]);
            // 최솟값 저장
            min = Math.min(right-left-1,min);
            
            if(map.get(key) === 1){
                // 한개라면 키를 지워버려 모든 상품이 포함된 것이 아니도록 만들어야함.
                map.delete(key);
                
            }else{
                // 한개가 아니라면, 중복으로 여러개들어와있는 것이므로 갯수를 줄인다.
                map.set(key, map.get(key)-1)
                
            }
            
            left++;
            
        }else{
          
        // 5개가 안되면 오른쪽을 늘린다.
          
            const key = gems[right]
            // 이미 있으면 +1, 아니면 1 
            map.set(key,map.get(key) ? map.get(key) + 1 : 1)
            
            right++;
            
        }
        
    }
  
    // 최솟 값 중 가장 먼저 나온 것이, left(시작 지점)이 가장 작은 요소임.
    const result = answer.find(([,,diff])=>{
        return diff === min 
    })
    
    // 리턴
    return result && [result[0]+1,result[1]+1]
}
answer.find 하여 min 값을 추출해내는 로직을 제거(객체를 활용하였다. 거리가 키값이 되어 가장 먼저 등장하는 요소만을 값으로 갖는다. 조회시 최단 거리 중 시작 지점이 가장 낮은 값
gemVariety 부분을 set을 활용하여 구현
function solution(gems) {
    
    let gemVariety = new Set(gems).size;
    let left = 0;
    
    let right = 0;
    
    let min = Number.MAX_SAFE_INTEGER
    
    const map = new Map();
    
    const answer = {};
    
    while( left <= right && right<=gems.length){
        // 5개가 되면 왼쪽을 늘린다.
        // 5개가 안되면 오른쪽을 늘린다.
        // 5개가 되는 시점에 answer 배열에 추가한다.
        if(map.size === gemVariety){
            const key = gems[left];
            
            
            
            min = Math.min(right-left-1,min);
            
            if(answer[right-left-1] === undefined){
                
               answer[right-left-1] = [left+1,right];
                
            }
            
            if(map.get(key) === 1){
                
                map.delete(key);
                
            }else{
                
                map.set(key, map.get(key)-1)
                
            }
            
            left++;
            
        }else{
            const key = gems[right]
            
            map.set(key,map.get(key) ? map.get(key) + 1 : 1)
            
            right++;
            
        }
        
    }
  
    return answer[min]
}