[프로그래머스]67258 : 보석 쇼핑 | 투포인트 탐색

2024. 10. 28. 16:46·코딩테스트/프로그래머스

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

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 


[python] 문제 풀이

 

  • 모든 보석 종류를 최소한 하나씩 포함하는 구간을 찾아야 함
  • 투 포인터를 활용해 구간을 효율적으로 줄여나감
  • 딕셔너리를 사용해 현재 구간에 포함된 보석의 개수를 관리

 

while end < len(gems):
    # end 포인터를 이동시키며 보석 추가
    if gems[end] in gem_count: 
        gem_count[gems[end]] += 1
    else:
        gem_count[gems[end]] = 1
    end += 1
  • while end < len(gems): end 포인터가 배열의 끝에 도달할 때까지 반복
  • if gems[end] in gem_count: 현재 end 포인터가 가리키는 보석이 gem_count에 이미 있는지 확인
    • 있으면: 그 보석의 개수 +1
      ex) 현재 gem_count에 DIA: 2가 있고, gems[end]가 DIA라면, gem_count = {"DIA": 3}
    • 없으면: 현재 구간에 처음으로 추가되는 것 -> 현재 구간에 이 보석의 개수를 1로 초기화
      ex)  gem_count가 빈 딕셔너리인 경우, gems[end]가 DIA라면, gem_count =  {"DIA": 1}
  • end += 1: end 포인터를 오른쪽으로 이동

 

while len(gem_count) == total_gems:
    # 현재 구간이 더 짧은 경우 갱신
    if end - start - 1 < result[1] - result[0]:
        result = [start, end - 1]
  • while len(gem_count) == total_gems: 현재 구간에 포함된 보석 종류의 수가 전체 보석 종류와 같을 때까지 반복
  • if end - start - 1 < result[1] - result[0]: 현재 구간의 길이(end - start - 1)가 기록된 최소 구간의 길이보다 짧으면 result를 업데이트
  • result - > 가장 짧은 구간의 시작과 끝 인덱스 저장 

 

 gem_count[gems[start]] -= 1
    if gem_count[gems[start]] == 0:
        del gem_count[gems[start]]  # 개수가 0이 되면 해당 보석 제거
    start += 1
  • gem_count[gems[start]] -= 1: start 포인터가 가리키는 보석의 개수 -1
  • if gem_count[gems[start]] == 0: 개수가 0이 되면 gem_count에서 그 보석을 삭제
  • start += 1: start 포인터를 오른쪽으로 이동

 


전체 코드

 

 

 

def solution(gems):
    total_gems = len(set(gems))  # 보석의 종류 수
    gem_count = {}  # 현재 구간의 보석 개수를 저장할 딕셔너리
    start, end = 0, 0
    result = [0, len(gems)]  # 최소 구간 초기값 = 전체 구간
    
    while end < len(gems):
        # end 포인터를 이동시키며 보석 추가
        if gems[end] in gem_count: 
            gem_count[gems[end]] += 1
        else:
            gem_count[gems[end]] = 1
        end += 1
        
        # 모든 종류의 보석을 포함하는 구간이 될 때까지 start 포인터 이동
        while len(gem_count) == total_gems:
            # 현재 구간이 더 짧은 경우 갱신
            if end - start - 1 < result[1] - result[0]:
                result = [start, end - 1]
            
            # start 포인터가 가리키는 보석을 빼고 한 칸 이동
            gem_count[gems[start]] -= 1
            if gem_count[gems[start]] == 0:
                del gem_count[gems[start]]  # 개수가 0이 되면 해당 보석 제거
            start += 1
    
    # 진열대 번호는 1번부터 시작하므로 결과에 +1
    return [result[0] + 1, result[1] + 1]

 

 

+) 코드 최적화

효율성이 너무 떨어지는 것 같아서 코드를 더 간결하게 하려고 해봤다.

 

여기서 key를 받는 구간을 더 간단하게 코드작성을 할 수 있다

if gems[end] in gem_count: 
            gem_count[gems[end]] += 1
        else:
            gem_count[gems[end]] = 1

 

gems_count[gems[end]] = gems_count.get(gems[end],0) + 1 # 키가 존재하면 get으로 키값 얻기

 

 

<동작 방식>

  1. gems_count.get(gems[end], 0): 현재 보석이 gems_count에 이미 있다면 해당 보석의 개수를 가져옴. 없다면 기본값 0을 반환
  2. gems_count[gems[end]] = ... + 1: 기존 개수에 1을 더해 업데이트

ex) gems = ["Ruby", "Emerald", "Ruby"]이고 gems_count = {}인 상태에서 end = 0이라면

gems_count[gems[0]] = gems_count.get(gems[0], 0) + 1

gems[0]은 "Ruby"이므로
gems_count.get("Ruby", 0) + 1 == 0 + 1 == 1
gems_count["Ruby"] = 1

확실히 조금 더 줄어들었음

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

[프로그래머스] 132265: 롤케이크 자르기 | 집합(set),counter  (1) 2024.11.04
[프로그래머스]150368: 이모티콘 할인 행사 | DFS  (2) 2024.10.21
[프로그래머스]43165: 타겟 넘버 | DFS  (0) 2024.10.14
[프로그래머스] 1154539 : Lv2 뒤에 있는 큰 수 찾기| 스택  (0) 2024.09.23
[프로그래머스] 12921번 : Lv1 소수 찾기 | 에라토스테네스의 체  (0) 2024.09.15
'코딩테스트/프로그래머스' 카테고리의 다른 글
  • [프로그래머스] 132265: 롤케이크 자르기 | 집합(set),counter
  • [프로그래머스]150368: 이모티콘 할인 행사 | DFS
  • [프로그래머스]43165: 타겟 넘버 | DFS
  • [프로그래머스] 1154539 : Lv2 뒤에 있는 큰 수 찾기| 스택
#코딩 공부
#코딩 공부
tildacoding 코딩 공부
  • #코딩 공부
    tildacoding
    #코딩 공부
  • 전체
    오늘
    어제
  • 글쓰기 관리자
  • Personal

    • 홈
    • 태그
    • 방명록
  • link

    • GITHUB
    • 분류 전체보기 (51)
      • Dev (12)
        • python (0)
        • 웹크롤링 (2)
        • 머신러닝 (3)
        • 딥러닝 (4)
        • 언어지능 딥러닝 (2)
        • SQL (1)
        • Spring (0)
      • 코딩테스트 (16)
        • 백준 (3)
        • 프로그래머스 (7)
        • 기타 문제 (2)
        • 코딩테스트를 위한 정리 (4)
      • Study (4)
        • 알고리즘 (2)
        • 자료구조 (2)
      • 대외활동 (18)
        • 에이블스쿨 (18)
        • 공모전 (0)
  • 공지사항

    • 루틴 skrrrrr
  • 인기 글

  • 태그

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
#코딩 공부
[프로그래머스]67258 : 보석 쇼핑 | 투포인트 탐색
상단으로

티스토리툴바