소피it블로그
[알고리즘] 투 포인터 알고리즘, 구간 합 계산 본문
자료 출처: https://youtu.be/cswJ1h-How0
1. 투 포인터 알고리즘 예시 문제: 특정한 합을 가지는 부분 연속 수열 찾기
- start, end가 0번째 인덱스를 가리키도록 함 (start <= end)
- 현재 부분 합이 M과 같다면 카운트해줌
- 현재 부분 합이 M보다 작다면 end += 1
- 현재 부분 합이 M보다 크다면 start += 1
- 모든 경우를 확인할 때까지 2~4번 과정을 반복한다.
n = 5
m = 5
data = [1, 2, 3, 2, 5]
count = 0
interval_sum = 0
end = 0
# 모든 원소 각각을 iteration마다 시작 인덱스로 하나씩 고정해놓고
for start in range(n):
# end를 가능한 만큼 이동시키기
# 이때 interval_sum이 m보다 커져서 while문을 벗어나게 되는 경우에는?
# start는 for문 안에서 고정에 end += 1을 계속 해봤자 interval_sum은 계속 커질 것이기 때문에 더 볼 필요 없음
# (data의 모든 원소가 양수라는 전제)
while end < n and interval_sum < m:
interval_sum += data[end]
end += 1
if interval_sum == m:
count += 1
# 이제 while문을 빠져나오고 for문은 다음 iteration으로 가야 하기 때문에 그 전에 처리할 것을 처리해줌
# 즉 기존의 start 인덱스의 원소를 interval_sum에서 빼준 후 start 인덱스를 다음 인덱스로 넘긴다.
interval_sum -= data[start]
print(count)
2. 구간 합
연속적으로 나열된 n개의 수중 특정 구간의 모든 수를 합한 값을 계산
- n개의 정수로 구성된 수열
- m개의 쿼리 정보: 각 쿼리는 left, right로 구성되며, 각 쿼리에 대하여 [left, right] 구간에 포함된 데이터들의 합을 출력
- 수행 시간 제한: O(n + m)
- 접두사 합(Prefix Sum): 배열의 맨 앞부터 특정 위치까지의 합을 미리 구해놓은 것
- n개의 수의 위치 각각에 대하여 접두사 합을 계산하여 별도의 배열 P에 저장
- 매 m개의 쿼리 정보를 확인할 때 구간 합은 P[right] - P[left - 1]
n = 5
data = [10, 20, 30, 40, 50]
sum_value = 0
prefix_sum = [0] # 인덱스 0부터 시작(data의 인덱스보다 앞에 하나 더 있다고 생각하기)
for i in data:
sum_value += i
prefix_sum.append(sum_value)
left = 3
right = 4
print(prefix_sum[right] - prefix_sum[left - 1])
'CS > 자료구조, 알고리즘 이론' 카테고리의 다른 글
[알고리즘] 소수 판별 알고리즘, 에라토스테네스의 체 알고리즘 파이썬 구현 (0) | 2022.10.02 |
---|---|
[알고리즘] 위상 정렬 파이썬 구현 (0) | 2022.10.01 |
[자료구조/알고리즘] 신장 트리, 최소 신장 트리, 크루스칼 알고리즘 파이썬 구현 (1) | 2022.10.01 |
[자료구조] 서로소 집합 (0) | 2022.10.01 |
[알고리즘] 플로이드 워셜 최단 경로 알고리즘 파이썬 구현 (0) | 2022.10.01 |