문제
개발자 출신으로 세계 최고의 갑부가 된 어피치는 스트레스를 받을 때면 이를 풀기 위해 오프라인 매장에 쇼핑을 하러 가곤 합니다.
어피치는 쇼핑을 할 때면 매장 진열대의 특정 범위의 물건들을 모두 싹쓸이 구매하는 습관이 있습니다.
어느 날 스트레스를 풀기 위해 보석 매장에 쇼핑을 하러 간 어피치는 이전처럼 진열대의 특정 범위의 보석을 모두 구매하되 특별히 아래 목적을 달성하고 싶었습니다.
'진열된 모든 종류의 보석을 적어도 1개 이상 포함하는 가장 짧은 구간을 찾아서 구매'
풀이
투포인터를 활용해서 푸는 문제
- left,right 포인터 모두 0번째부터 시작해서, right 포인터를 오른쪽으로 옮기면서 선택한 보석은 map 구조에 (이름,개수) 로 저장
- map의 size가 해당 문제에서 나온 보석 종류와 같다면 - 해당 구간을 기록해놓고 0번째에 있던 left 포인터를 이동시키면서, 선택한 보석은 map구조에서 개수를 -1씩 해줌
- 개수가 0이 되면 map에서 delete하고, map의 size가 바뀌었기 때문에 다시 right 포인터를 이동시키면서, index 끝까지 가게되면 종료
이렇게 하면 중간에 다 찾았다고 끊기는 것이 아니라 새로운 경우의 수를 찾아줄 수 있고, 모든 보석을 찾았을 때마다 기존의 값과 비교해서 더 짧은 것으로 업데이트 해주면 됨
size를 체크해줘야 하기 때문에 객체보다는 map을 사용하는게 더 편한거같음
코드
function solution(gems) {
const 젬종류수 = new Set(gems).size
let [left,right] = [0,0]
let answer = [1,gems.length]
const store = new Map()
while(right <= gems.length){
//젬을 다 못담았으면 right를 늘리고
//젬을 다 담았으면 그때의 answer값을 바꿔주고 left 늘리기
if(store.size === 젬종류수){
if(answer[1] - answer[0] >= right - left){
answer = [left+1,right]
}
store.set(gems[left],store.get(gems[left])-1)
if(store.get(gems[left]) === 0){store.delete(gems[left])}
left ++
}
else{
store.set(gems[right],(store.get(gems[right]) || 0) + 1)
right ++
}
}
return answer
}
'JS' 카테고리의 다른 글
프로그래머스 - 괄호 변환 JS (0) | 2023.08.01 |
---|---|
import한 함수 에러 처리법 (0) | 2023.07.22 |
프로그래머스 - 인사고과 JS (0) | 2023.07.13 |
프로그래머스 - 큰 수 만들기 JS (0) | 2023.07.12 |
프로그래머스 - 셔틀버스 JS (0) | 2023.06.30 |