https://github.com/Dev-Guccin
Guccin
https://github.com/Dev-Guccin
전체 방문자
오늘
어제
  • 분류 전체보기 (172)
    • 알고리즘 (140)
    • 삽질방지 (13)
    • SystemHacking (1)
    • 일상 (4)
    • 개발 (8)
    • 스프링 부트 REST API 개발일지 (5)
    • JPA (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 큐
  • 프로그래머스
  • python3
  • BFS
  • 유클리드호제법
  • 다이나믹프로그래밍
  • 파이썬
  • 유니온 파인드
  • heapq
  • 재귀
  • MST
  • 재귀함수
  • 이분탐색
  • 다이나믹 프로그래밍
  • 최소힙
  • DFS
  • DP
  • 최단경로
  • Python
  • 12015
  • 그래프
  • 이분 탐색
  • 최대공약수
  • LIS
  • 백트래킹
  • 스택
  • 백준
  • 그리디
  • counter
  • 다익스트라

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
https://github.com/Dev-Guccin

Guccin

[python3] 프로그래머스 징검다리 풀이 ( 이분탐색 )
알고리즘

[python3] 프로그래머스 징검다리 풀이 ( 이분탐색 )

2021. 8. 22. 16:06

왜 이분 탐색문제인지 이해를 할수가 없어서 상당히 헤맸다. 결국 풀이를 봤다.

우선 문제를 읽어보면, 징검다리를 만들 때 n만큼 돌을 제거하고 최솟값을 찾는다. 이때 최솟값을 최대로 만드는 경우를 구하면 된다. 
제한사항을 보면 distance가 1~1,000,000,000이다. 아무래도 선형탐색은 못할 만큼 값이 크다. 따라서 여기서 이분탐색의 냄새를 살짝 맡아본다.

처음에 나는 각 돌마다 거리를 구하고 작은 값부터 제거하면 되지 않나?하고 생각했다. 그러나 문제는 돌이 제거되면 각 돌의 거리를 다시 최신화 해주어야 한다. 그럼 돌을 제거 할 때마다 sort를 하게 되고 n만큼 sort를 해야되는 상황이 발생한다. 

그럼 생각을 바꿔보자 만약 최솟값을 기준으로 현재 바위가 만족하는지 확인한다고 가정한다. 예를 들어 최솟값이 5라고 가정한다. 처음 0에서 25까지 중에서 [2,11,14,17,21] 을 순서대로 추가하면서 거리가 5보다 크다면 제거해본다.

0 2 11 14 17 21 25

 결과적으로 최솟값을 5로 잡는다면 우리가 제거해야 할 돌 n은 3개가 된다.

 

그럼 이번에는 최솟값을 4로 잡아본다. 그리고 거리가 4보다 크다면 제거한다.

0 2 11 14 17 21 25

결과적으로 최솟값을 4로 잡는다면 우리가 제거해야 할 돌 n은 2개가 된다.  n은 2이기 때문에 만족한다.

 

이러한 방식으로 최솟값을 기준으로 n을 만족하는 최대 최솟값을 구할 수 있다. 
그렇다면 문제는 최솟값의 후보가 1~distance(1,000,000,000)까지라 너무 크다는 것이다. 아까 이분탐색의 냄새를 맡았다면 최솟값을 이분탐색으로 비교하면서 최대 최솟값을 구하면 된다는 생각이 떠오른다.
따라서 최솟값을 이분탐색으로 정하고, n을 만족하는 경우 더 큰 최솟값을 구해보기 위해 L = M+1로, n을 만족하지 않는 경우에는 이전보다 작은 최대 최솟값을 구하기 위해 R=M-1을 해주면 된다.

이제 코드를 작성하면 된다.

def solution(distance, rocks, n):
    rocks = sorted(rocks) # 정렬해주기
    rocks_num = len(rocks)
    L = 1
    R = distance
    final = 0
    while L<=R:
        M = int((L+R)/2) # 예상하는 최솟값
        remove = 0
        tmp_rocks = [0]
        for i in range(rocks_num):
            if (rocks[i] - tmp_rocks[-1] >= M) and (distance - rocks[i] >= M):# 다리 놓기 가능
                tmp_rocks.append(rocks[i])
            else: # 다리 못놓음
                remove += 1
        if remove <= n:
            final = M
            L = M+1
        else:
            R = M-1
    return final

 

결론 : 아 이분탐색 어렵다....거꾸로 생각해보는 습관을 들이자

저작자표시

'알고리즘' 카테고리의 다른 글

#5 알고리즘 공부 8/24 리뷰  (0) 2021.08.24
[python3] 백준 2110 풀이 ( 공유기 설치, 이분탐색 )  (0) 2021.08.24
코딩테스트 알고리즘별 전략 및 요약 (수정 중...)  (0) 2021.08.20
[python3] 백준 1916 풀이 ( 최소비용 구하기, 다익스트라, 그래프 )  (0) 2021.08.19
[python3] 백준 1389 풀이 ( 케빈 베이컨의 6단계 법칙, 플로이드 워샬 )  (0) 2021.08.18
    '알고리즘' 카테고리의 다른 글
    • #5 알고리즘 공부 8/24 리뷰
    • [python3] 백준 2110 풀이 ( 공유기 설치, 이분탐색 )
    • 코딩테스트 알고리즘별 전략 및 요약 (수정 중...)
    • [python3] 백준 1916 풀이 ( 최소비용 구하기, 다익스트라, 그래프 )
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin

    티스토리툴바