Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 파이썬백준
- 코딩테스트유형
- 코딩테스트
- mysql
- sql server 포트번호
- blob파일업로드
- 프로그래머스
- 코테유형
- BLOB
- queryasync
- c#blob
- blob파일다운로드
- frontend
- blob다운로드오류
- blobcontainer
- sql풀이
- 알고리즘
- export to excel
- 파이썬
- 취업코데
- C#
- 로컬포트번호
- asp.net
- c# 엑셀추출
- 프로그래머스MYSQL
- sql
- 투포인터예제
- 프로그래머스SQL
- 코테
- 백준
Archives
- Today
- Total
개발새발
알고리즘 :: 투포인터 예제 백준 1806 파이썬 본문
투 포인터(Two Pointers) 알고리즘은 배열이나 리스트에서 특정 조건을 만족하는 부분 배열이나 부분 집합을 찾기 위해 두 개의 포인터를 사용하는 기법입니다. 이 기법은 주로 배열을 효율적으로 탐색하면서 O(N^2) 이상의 시간 복잡도를 O(N)으로 줄일 때 사용됩니다.
투 포인터 기법의 기본 원리
- 포인터 초기화:
- 배열의 시작 위치에 두 개의 포인터를 설정합니다. 일반적으로 하나는 start 포인터, 다른 하나는 end 포인터입니다.
- 포인터 이동:
- 조건을 만족할 때까지 두 포인터를 이동시킵니다.
- 각 포인터의 이동은 문제의 조건에 따라 다릅니다. 예를 들어, 부분합이 일정 값을 넘는 경우 start 포인터를 이동시키고, 그렇지 않으면 end 포인터를 이동시킵니다.
- 조건 만족 확인:
- 두 포인터가 가리키는 구간이나 값이 문제의 조건을 만족하는지 확인합니다.
- 조건을 만족하면 필요한 계산을 수행하거나 결과를 갱신합니다.
- 종료 조건:
- 일반적으로 end 포인터가 배열의 끝에 도달하면 반복을 종료합니다.
투 포인터 기법의 예제: 부분합이 특정 값 이상이 되는 가장 짧은 부분 배열의 길이 찾기
문제 설명
- 주어진 배열에서 연속된 수들의 부분합 중 특정 값 이상이 되는 가장 짧은 부분 배열의 길이를 구합니다.
알고리즘 단계
- 포인터 초기화:
- start와 end 포인터를 배열의 시작 위치인 0으로 초기화합니다.
- current_sum을 0으로 초기화하여 현재 부분합을 추적합니다.
- min_length를 무한대로 초기화하여 최소 부분 배열의 길이를 추적합니다.
- 포인터 이동 및 부분합 계산:
- end 포인터를 오른쪽으로 이동시키며 current_sum에 현재 end가 가리키는 값을 더합니다.
- current_sum이 특정 값 S 이상이 되면 start 포인터를 오른쪽으로 이동시키며 current_sum에서 start가 가리키는 값을 뺍니다.
- 이 과정에서 부분합이 S 이상인 경우의 길이를 계산하여 min_length를 갱신합니다.
- 결과 반환:
- 반복이 종료된 후 min_length가 갱신되지 않았다면 조건을 만족하는 부분 배열이 없다는 의미이므로 0을 반환합니다.
- 그렇지 않으면 min_length를 반환합니다.
예제 코드
import sys
def min_subarray_length(N, S, arr):
start = 0
end = 0
current_sum = 0
min_length = sys.maxsize
while True:
if current_sum >= S:
# start를 이동하고, sum = 0 , end = start로 초기화할 수도 있지만
# 어차피 S보다 작은 값이므로 한번 더 연산을 수행하지 않고 start만 이동하여 계산함
min_length = min(min_length, end - start)
current_sum -= arr[start]
start += 1
elif end == N:
break
else:
current_sum += arr[end]
end += 1
return 0 if min_length == sys.maxsize else min_length
# 입력
N, S = map(int, input().split())
arr = list(map(int, input().split()))
# 결과 출력
print(min_subarray_length(N, S, arr))
코드 설명
- 입력 받기:
- N과 S를 입력받고, 수열을 arr에 저장합니다.
- 함수 정의:
- min_subarray_length 함수에서 투 포인터 기법을 사용하여 부분합이 S 이상이 되는 가장 짧은 부분 배열의 길이를 찾습니다.
- 투 포인터 초기화:
- start와 end를 0으로 초기화하고, current_sum을 0으로 설정합니다.
- min_length를 무한대로 설정합니다.
- 포인터 이동 및 부분합 계산:
- end를 증가시키며 current_sum에 arr[end]를 더합니다.
- current_sum이 S 이상이 되는 동안 start를 증가시키며 부분합을 줄이고, 부분 배열의 길이를 계산하여 min_length를 갱신합니다.
- 결과 반환:
- min_length가 갱신되지 않았다면 0을 반환하고, 그렇지 않으면 min_length를 반환합니다.
이 코드는 투 포인터 기법을 사용하여 각 요소를 한 번씩만 처리하므로 시간 복잡도는 O(N)입니다.
'코딩테스트 > 알고리즘' 카테고리의 다른 글
크루스칼 알고리즘 :: 백준 1197 파이썬 (0) | 2024.06.26 |
---|---|
알고리즘 :: 다익스트라(그래프 이론) 예제 1916 파이썬 (0) | 2024.06.25 |
코딩테스트 자주 출제되는 알고리즘 유형, 각 알고리즘 별 문제 접근 방법 (0) | 2024.06.24 |
Comments