[프로그래머스] 보석 쇼핑 JavaScript

0

Problem Solving

목록 보기
33/49

https://school.programmers.co.kr/learn/courses/30/lessons/67258#

풀이

처음에는 투포인터를 이용해 풀이를 하려고했다.
하지만 가능한 경우의 수가 여러가지가 될 수 있는 케이스에 대해서 틀려버렸다.
오랜시간 고민하다 Map으로 인덱스를 저장하고 경우의 수를 저장해놔야 한다는 설명을 보게 되었고, Map으로 풀이했다.

첫번째 풀이 (시간초과)

이렇게 하면 정확성은 통과하지만, 효율성은 통과하지 못했다.
계속 Map의 보석에 대해서 업데이트를 하고 min을 계산하면 되겠다고 생각을 했는데,
gems array의 길이가 길어지다보니 min이 상당히 오랜시간 잡아먹나보다.

function solution(gems) {
    const resultLength = new Set(gems).size;
    let gemsTable = new Map();
    let answer = [];
    
    for (let i=0; i<gems.length; i++){
        gemsTable.set(gems[i], i);
        if(gemsTable.size === resultLength){
            answer.push([Math.min(...gemsTable.values())+1, i+1])
        }
    }
    answer.sort((a,b)=>{
        if((a[1]-a[0]) > (b[1]-b[0])) return 1;
        if((a[1]-a[0]) < (b[1]-b[0])) return -1;
        if(a[0] > b[0]) return 1;
        if(a[0] < b[0]) return -1;
    })
    return answer[0];
}

두번째 풀이 (통과)

계속 delete와 set을 해주면 첫번째 항목은 무조건 작은 인덱스가 들어갈 수 밖에 없는 점을 고려한 풀이다.
이런식으로 하면 업데이트된 수 중에서 가장 작은 수를 쉽게 구할 수 있다.
많은 것들을 얻어간 문제였다..!

function solution(gems) {
    const resultLength = new Set(gems).size;
    let gemsTable = new Map();
    let answer = [];
    // for문을 돌면서 gem table 업데이트
    for (let i=0; i<gems.length; i++){
        gemsTable.delete(gems[i]) //기존에 있는 보석 삭제
        gemsTable.set(gems[i], i) //보석 index 업데이트
      	//내 테이블의 size와 총 갯수가 같다면 
        if(gemsTable.size === resultLength){
          	//가장 첫 항목의 인덱스와 현재 인덱스를 담는다.
            answer.push([gemsTable.values().next().value+1, i+1])
        }
    }
  	// end-start 차이가 가장 작으면서 start가 작은 것이 정답임
    answer.sort((a,b)=>{
        if((a[1]-a[0]) > (b[1]-b[0])) return 1;
        if((a[1]-a[0]) < (b[1]-b[0])) return -1;
        if(a[0] > b[0]) return 1;
        if(a[0] < b[0]) return -1;
    })
    return answer[0];
}

사람들은 정말 똑똑하다..

0개의 댓글