[ProblemSolving] 백준 - 1806 부분합 (투포인터)
문제 링크
문제 설명
10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다.
출력
첫째 줄에 구하고자 하는 최소의 길이를 출력한다. 만일 그러한 합을 만드는 것이 불가능하다면 0을 출력하면 된다.
예제 입력1
10 15
5 1 3 5 10 7 4 9 2 8
예제 출력1
2
나의 풀이 1
투포인터
으로 해결한다.
start, end 를 0으로 셋팅하고 end가 n이 될 때까지 반복문을 진행한다.
- end를 하나씩 이동하면서 temp에 누적하고, end를 1증가
- temp값이 s 이상이라면 length에 최소 길이를 구해준다.
temp에서 start에 위치한 요소를 빼주고, start는 오른쪽으로 한칸씩 이동한다. - end가 배열의 끝에 다다를 때까지 반복한다.
메모리 | 시간 |
---|---|
40748 KB | 172 ms |
나의 코드
n, s = map(int, input().split())
arr = list(map(int, input().split()))
start , end = 0, 0
temp =0
length = n+1
while True:
if temp >= s:
length = min(length, end-start)
temp -= arr[start]
start += 1
elif end == n:
break
else:
temp += arr[end]
end += 1
if length == n+1:
print(0)
else:
print(length)
다른 분 풀이 2
메모리 | 시간 |
---|---|
39756 KB | 116 ms |
while 대신 for 반복문을 이용한 더 직관적이고 쉬운 코드인 것 같다.
코드
from sys import stdin
input = stdin.readline
def solve():
N, S = map(int, input().split())
arr = list(map(int, input().split()))
inf = float('inf')
left, sum_val, ans= 0, 0, inf
for right in range(N):
sum_val += arr[right]
while sum_val - arr[left] >= S:
sum_val -= arr[left]
left += 1
if sum_val >= S and ans > right - left:
ans = right - left + 1
print(ans if ans != inf else 0)
return
solve()
Author And Source
이 문제에 관하여([ProblemSolving] 백준 - 1806 부분합 (투포인터)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@redcarrot01/ProblemSolving-백준-1806-부분합-투포인터저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)