📊 Algorithm/Algorithm 주제별 정리

🧚‍♂️알고리즘🧚‍♂️ - 이진탐색

정람지 2023. 3. 1. 01:43

이진 탐색(이분 탐색)

데이터가 정렬되어 있는 상태에서 원하는 값을 찾아내는 알고리즘

대상 데이터의 중앙값과 찾고자 하는 값을 비교해 데이터의 크기를 절반씩 줄이면서 대상을 찾음

 

기본 틀

1. 데이터 오름차순(내림차순) 정렬하기
2. 현재 데이터셋의 중앙값(mid)  선택
3. 중앙값 > 타깃 데이터일 때 중앙값 기준으로 왼쪽 데이터셋을 선택한다. (mid값을 바꾸는 방법 사용)
4. 중앙값 <  타깃 데이터일 때 중앙값 기준으로 오른쪽 데이터셋을 선택한다.
5. 과정 2-4를 반복하다가 중앙값 = 타깃 데이터일 때 탐색을 종료한다.

 

완전탐색의 시간복잡도 ( O(N^2),  O(N!), 등) 

이분 탐색의 시간복잡도 ( O(logN))밑2

열심히만듦(doit 참고)


실버 4

1920

 

1920번: 수 찾기

첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들

www.acmicpc.net


실버1 

2343

 

2343번: 기타 레슨

강토는 자신의 기타 강의 동영상을 블루레이로 만들어 판매하려고 한다. 블루레이에는 총 N개의 강의가 들어가는데, 블루레이를 녹화할 때, 강의의 순서가 바뀌면 안 된다. 순서가 뒤바뀌는 경

www.acmicpc.net

블루레이의 크기가 모두 같고 녹화 순서가 바뀌지 않아야 함이라는 문제 조건 => 이진탐색 알고리즘 사용

 

중간값 = 블루레이의 크기

블루레이의 크기가 될 수 있는 최솟값 = 최대 길이의 레슨시간 = 시작인덱스

블루레이의 크기가 될 수 있는 최댓값 = 최대 길이의 레슨시간 = 종료인덱스

 

중앙값(블루레이) 크기로 모든 레슨을 저장할 수 있다면 종료인덱스 = 중앙값-1

중앙값(블루레이) 크기로 모든 레슨을 저장할 수 없다면 종료인덱스 = 중앙값+1

 

이진탐색 : 목표치를 찾을 때가 아닌 최솟값(최종 시작인덱스값)/최댓값(최종 종료인덱스값) 을 찾을 때도 사용 가능

from sys import stdin
N, M = map(int,stdin.readline().split()) #레슨 수  블루레이 개수
Llist = list(map(int,stdin.readline().split()))

start = max(Llist) # 블루레이의 최소크기후보, 최대 길이의 레슨시간  <= 여기에 가까워야 함
end = sum(Llist) # 블루레이의 최대크기후보, 모든 레슨시간의 합

while(start <= end):
    mid = (start+end)//2 #블루레이크기후보

    BlueNum = 1 # mid크기일 시 블루레이 개수
    oneBlue = 0 #각 블루레이크기 확인 변수
    for cha in Llist:
        if oneBlue+cha <= mid:
            oneBlue += cha
        else:
            oneBlue = cha
            BlueNum += 1
    
    if ( BlueNum <= M ): # 최소를 구해야 하므로 개수가 M과 같을 때도 값을 줄임
        end = mid-1
    else:
        start = mid + 1

print(start)

왜 start를 출력할까?

마지막에는 반드시 BlueNum <= M 조건에 걸림/ end가 감소함

왜 ㄱ렇냐면,

최종 시작/종료 인덱스 값은 start > end가 된 처음이므로, 홀리

 

 

 

항상 최종적으로 end랑 start는 1밖에 차이가 안 나므로 end+1을 해도 됨

왜 그렇냐면,

홀리카몰리난멍청이야

지금은 물러나지만 다음에 돌아와 조져주겟어 기다리도록

 

이분 탐색(Binary Search) 헷갈리지 않게 구현하기

개요 이분 탐색은 off-by-one error가 발생하기 쉬워서 늘 헷갈립니다. 이분 탐색 문제를 풀다보면 탈출 조건으로 lo <= hi, lo < hi, lo + 1 < hi 중 어느 걸 선택해야 할 지, 정답이 lo인지 hi인지 (lo + hi) / 2

www.acmicpc.net

while문 조건을 뭐로 할지 ( start <= end, start < end, start + 1 < end ..)

정답으로 무엇을 출력해야 할지 (start, end...)

 많이 헷갈리는 이분탐색, 위 포스팅 보고 정리!


골드2

1300

 

1300번: K번째 수

세준이는 크기가 N×N인 배열 A를 만들었다. 배열에 들어있는 수 A[i][j] = i×j 이다. 이 수를 일차원 배열 B에 넣으면 B의 크기는 N×N이 된다. B를 오름차순 정렬했을 때, B[k]를 구해보자. 배열 A와 B

www.acmicpc.net