전공공부/알고리즘&자료구조

투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window)

milkteagood 2020. 1. 12. 18:38
728x90
반응형

알고리즘 설명 출처: https://m.blog.naver.com/kks227/220795165570

 

투 포인터(Two Pointers Algorithm), 슬라이딩 윈도우(Sliding Window) (수정: 2019-09-09)

조금 성향이 비슷하다고 생각하는 기법 2개를 함께 쓰려 합니다.첫 번째로 소개해드릴 기법은 투 포인터(tw...

blog.naver.com

 

투포인터 혹은 스라이딩 윈도우 기법은 연속적인 구간의 합이나 경우의 수를 구할때 매우 유용하다.

처음에 두개의 포인트 P1,P2를 설정하고 예를들어 배열의 구간 합이 특정 값을 만족할때  그 값을 만족하는 구간의 수를 구하는 문제가 있다. 이떄 배열이 모두 양수라고 가정을 하면 p2가 커질수록 합은 계속 증가하게 된다. 그래서 만약 합이 커지다가 특정 수를 초과하게되면 이제 반대로 p1값을 증가시키게된다. 왜냐하면 p1이 증가할수록 p1 p2가 포함하고 있는 구간의 범위가 줄어들기때문에 구간의 합도 작아지게된다. 

 

좀더 자세히 알고리즘 순서를 적자면 (순서가 매우 중요하다!)

 

1. 초기 p1,p2,sum,cnt(경우의 수) 0으로 설정 , 구간합 기준m설정

2. while(true)안에 넣기

3-1. 만약 sum이 m보다 크거나 같다면 sum-=arr[p1]을 한 후에 p1++로 카운트를 하나 올린다.

   2. 아니고 만약 p2==n이라면 (p2가 배열의 마지막 인덱스인n-1 까지 찍고 그다음인 n에 도달했다면 반복문을 탈출

   3. 만약 sum이 m보다 작다면 sum+=arr[p2]을 한 후에 p2++로 카운트를 하나 올린다.

4. 만약 sum==m이라면 cnt카운트값을 증가시킨다.

 

만약 3-1,3-2의 순서가 바뀐다면 그 전상황에서 p2를 카운트시켜 값이 증가했는데 단지 도착점에 도달했다는 이유때문에 그때 sum이 m보다 크거나 같아서 아직 p1을 더 올려가며 cnt값을 증가시킬 수 있는데 이것을 더해주지 못하고 종료하게 된다. 따라서 위와같은 순서를 반드시 지켜줘야 투포인터 알고리즘이 정상적으로 작동하게 된다.

 

투포인터 알고리즘 예제

백준: 2003 수들의 합/ 출처: https://www.acmicpc.net/problem/2003

 

2003번: 수들의 합 2

첫째 줄에 N(1≤N≤10,000), M(1≤M≤300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.

www.acmicpc.net

소스코드

 

그밖에도 투포인터 알고리즘과 관련된 문제

https://www.acmicpc.net/problem/7453

 

7453번: 합이 0인 네 정수

문제 정수로 이루어진 크기가 같은 배열 A, B, C, D가 있다. A[a], B[b], C[c], D[d]의 합이 0인 (a, b, c, d) 쌍의 개수를 구하는 프로그램을 작성하시오. 입력 첫째 줄에 배열의 크기 n (1 ≤ n ≤ 4000)이 주어진다. 다음 n개 줄에는 A, B, C, D에 포함되는 정수가 공백으로 구분되어져서 주어진다. 배열에 들어있는 정수의 절댓값은 최대 228이다. 출력 합이 0이 되는 쌍의 개수를 출력한다. 예제 입력 1 복

www.acmicpc.net

https://www.acmicpc.net/problem/2143

 

2143번: 두 배열의 합

첫째 줄에 T(-1,000,000,000 ≤ T ≤ 1,000,000,000)가 주어진다. 다음 줄에는 n(1 ≤ n ≤ 1,000)이 주어지고, 그 다음 줄에 n개의 정수로 A[1], …, A[n]이 주어진다. 다음 줄에는 m(1≤m≤1,000)이 주어지고, 그 다음 줄에 m개의 정수로 B[1], …, B[m]이 주어진다. 각각의 배열 원소는 절댓값이 1,000,000을 넘지 않는 정수이다.

www.acmicpc.net

https://www.acmicpc.net/problem/1806

 

1806번: 부분합

문제 10,000 이하의 자연수로 이루어진 길이 N짜리 수열이 주어진다. 이 수열에서 연속된 수들의 부분합 중에 그 합이 S 이상이 되는 것 중, 가장 짧은 것의 길이를 구하는 프로그램을 작성하시오. 입력 첫째 줄에 N (10 ≤ N < 100,000)과 S (0 < S ≤ 100,000,000)가 주어진다. 둘째 줄에는 수열이 주어진다. 수열의 각 원소는 공백으로 구분되어져 있으며, 10,000이하의 자연수이다. 출력 첫째 줄에 구하고자 하는 최소의 길

www.acmicpc.net

 

728x90
반응형