부분 구간의 후보 개수는 NC2 이고, 이를 하나하나 살펴보는 것은 2중 for문이면 충분하다.
후보의 개수가 NC2인 이유는 인덱스 2개를 뽑으면 작은 수와 큰 수가 각각 부분의 시작점과 끝점에 대응되기 때문임
이 방법의 시간 복잡도는 O(N2)이므로 이 방법으로도 문제를 해결할 수 있다!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
시작점을 l, 끝점을 r으로 설정하고 투 포인터 알고리즘을 진행하며 l을 기준으로 r을 살펴보면 된다.
이러한 과정이 두 개의 포인터가 나란히 이동하는 것처럼 보여서 투 포인터 알고리즘이라고 하는 것이다.
하지만, 이러한 과정은 위에서 설명한 사고과정에 기반하여 나와야 한다는 것을 잊지말자.
아래와 같은 배열에 대해서 투 포인터 알고리즘을 이용하여 답을 구해보자. (N=10, M=5)
[초기 설정] 답(합이 M인 부분구간의 개수)을 저장하는 변수 res를 0으로 초기화 현재 부분 구간의 합을 저장하는 변수 cur_sum을 0으로 초기화 현재 부분 구간의 끝점을 나타내는 변수 r을 -1으로 초기화
[1단계] l = 0 l=0, r=-1, cur_sum=0, res=0
현재 부분 구간 [0, -1]에서 인덱스가 0인 원소(1)를 추가하면 cur_sum = 0+1 ≤ M(5) 이므로r=0으로 갱신 현재 부분 구간 [0, 0]에서 인덱스가 1인 원소(2)를 추가하면 cur_sum = 1+2 ≤ M(5) 이므로 r=1으로 갱신 현재 부분 구간 [0, 1]에서 인덱스가 2인 원소(2)를 추가하면 cur_sum = 3+3 > M(5) 이므로 stop
[2단계] l = 1 l=1,r=1, cur_sum=2, res=0 l이 1이 되면서 인덱스가 0인 원소를 빼줘야 하므로 cur_sum = 3-1 = 2로 시작
현재 부분 구간 [1, 1]에서 인덱스가 2인 원소(3)를 추가하면 cur_sum = 2+3 = M(5) 이므로 r=2으로 갱신, res += 1 현재 부분 구간 [1, 2]에서 인덱스가 3인 원소(4)를 추가하면 cur_sum = 5+4 >M(5) 이므로 stop
[3단계] l = 2 l=2,r=2, cur_sum=3, res=1 l이 2가 되면서 인덱수가 1인 원소를 빼줘야 하므로 cur_sum = 5-2 = 3로 시작
현재 부분 구간 [2, 2]에서 인덱스가 3인 원소(4)를 추가하면 cur_sum = 3+4 >M(5) 이므로 stop
[4단계] l = 3 l=3, r=2, cur_sum=0, res=1 l이 3이 되면서 인덱스가 2인 원소를 빼줘야 하므로 cur_sum = 3-3 = 0로 시작
현재 부분 구간 [3, 2]에서 인덱스가 3인 원소(4)를 추가하면 cur_sum = 0+4 ≤ M(5)이므로 r=3으로 갱신 현재 부분 구간 [3, 3]에서인덱스가 4인 원소(2)를 추가하면 cur_sum = 4+2 > M(5)이므로 stop
ㆍㆍㆍ
[6단계] l = 5 l=5, r=4, cur_sum=0, res=1 l이 5가 되면서 인덱스가 4인 원소를 빼줘야 하므로 cur_sum = 2-2 = 0로 시작
현재 부분 구간 [5, 4]에서 인덱스가 5인 원소(5)를 추가하면 cur_sum = 0+5 = M(5) 이므로 r=2으로 갱신, res += 1 현재 부분 구간 [5, 5]에서 인덱스가 6인 원소(3)를 추가하면 cur_sum = 5+3 > M(5)이므로 stop
[7단계] l = 6 l=6, r=5, cur_sum=0, res=2 l이 6이 되면서 인덱스가 5인 원소를 빼줘야 하므로 cur_sum = 5-5 = 0로 시작
현재 부분 구간 [6, 5]에서 인덱스가 6인 원소(3)를 추가하면 cur_sum = 0+3 ≤ M(5) 이므로r=6으로 갱신 현재 부분 구간 [6, 6]에서 인덱스가 7인 원소(1)를 추가하면 cur_sum = 3+1 ≤ M(5) 이므로r=7으로 갱신 현재 부분 구간 [6, 7]에서 인덱스가 8인 원소(1)를 추가하면 cur_sum = 4+1 = M(5) 이므로 r=8으로 갱신, res += 1 현재 부분 구간 [6, 8]에서 인덱스가 9인 원소(2)를 추가하면 cur_sum = 5+2 > M(5) 이므로 stop
[8단계] l = 7 l=7, r=8, cur_sum=2, res=3 l이 7이 되면서 인덱스가 6인 원소를 빼줘야 하므로 cur_sum = 5-3 = 2로 시작
현재 부분 구간 [7, 8]에서 인덱스가 9인 원소(2)를 추가하면 cur_sum = 2+2 ≤ M(5) 이므로 r=9으로 갱신 r이 배열의 배열의 끝까지 도달하였으므로 종료!
따라서, 우리는 배열에서 부분 구간의 합이 M(5)인 부분 구간은 res(3)개라는 것을 알 수 있다.
이 풀이는 l과 r이 배열의 크기만큼 이동하므로 시간 복잡도는 O(N)이다.
따라서, N의 범위가 1 ≤ N ≤ 100,000인 경우에도 사용할 수 있는 풀이라고 할 수 있다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters