-
[Algorithm] ํฌ ํฌ์ธํฐ ์๊ณ ๋ฆฌ์ฆ (Two Pointer Algorithm)Algorithm 2023. 5. 2. 01:57
ํฌ ํฌ์ธํฐ ๊ธฐ๋ฒ์ด๋?
- 2๊ฐ์ ํฌ์ธํฐ๋ฅผ ๋ง๋ค์ด์ ๊ฐ๊ฐ์ด ๊ฐ๋ฆฌํค๋ ์์์ ์๋ฏธ๋ฅผ ๋ถ์ฌํ์ฌ ์๊ตฌํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์๊ณ ๋ฆฌ์ฆ
- O(N^2)๋ฅผ O(N)์ผ๋ก ์ค์ผ ์ ์๋ค.
- ๋๋ค์๋ ์ ๋ ฌ๋ ๋ฐฐ์ด์์ ์ฌ์ฉํ๋ค. ์ ๋ ฌ๋ ๋ฐฐ์ด์์ O(N^2) ํ์ ์ค ํ์ ์๋ ์ฐ์ฐ์ ๋ฒ๋ ค์ O(N)์ผ๋ก ์ค์ธ๋ค.
- ํฌ์ธํฐ์ ์๋ฏธ๋ฅผ ๋ถ์ฌํ๋ ์์ ์ ๋ํ ์์๋ค์ ๋ค์ํ๊ฒ ์ ํด์ผ ํ๋ค.
ํฌ ํฌ์ธํฐ ๋ํ ์ ํ
- ํฌ์ธํฐ 2๊ฐ๊ฐ ์๋์์ ๋ฐ๋๋ก ์งํํด ๋์๊ฐ๋ ๋ฐฉ์
- ํฌ์ธํฐ 2๊ฐ๊ฐ ๊ฐ์ ๋ฐฉํฅ์ผ๋ก ์งํํด ๋์๊ฐ๋ ๋ฐฉ์
- ํฌ์ธํฐ ํ๋๋ ํ์ชฝ ๋ฐฉํฅ์ผ๋ก๋ง ์งํํ๊ณ , ๋ค๋ฅธ ํฌ์ธํฐ๋ ์์ชฝ์ผ๋ก ์ด๋ํ๋ ๊ฒ
ํฌ ํฌ์ธํฐ ๋์ ์๋ฆฌ
10๊ฐ์ ์๋ก ๋ค๋ฅธ ์์ ์ ์๋ก ์ ๋ ฌ๋ ์์ด์์, ๋ ์ (i, j)์ ํฉ์ด 13์ ๋ง์กฑํ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ตฌํ์์ค. (1 ≤ i < j ≤ n = 10)
๋ง์ฝ ์ ๋ฌธ์ ๋ฅผ ์์ ํ์์ผ๋ก ํ ๊ฒฝ์ฐ, ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค. ์ด ๋์ ์๊ฐ ๋ณต์ก๋๋ O(N^2)์ด๋ค.
int answer = 0; for (int i = 0; i < 10; i++) { for (int j = i + 1; j < 10; j++) { if (arr[i] + arr[j] == 13) answer++; } }var answer = 0 for i in 0..<10 { for j in i..<10 { if (arr[i] + arr[j] == 13) { answer += 1 } } }๋จผ์ ์์ ํ์์ ์งํํด๋ณด๋ฉด,

์ธ๋ฑ์ค i = 3, j = 5์ผ ๋ arr[3] + arr[5] = 13์ด๋ฏ๋ก answer์ 1 ์ฆ๊ฐ์ํจ๋ค.

์ด์ j๊ฐ 1 ์ฆ๊ฐํ๋๋ฐ, arr[3] + arr[6] = 14 > 13์ด๊ธฐ ๋๋ฌธ์, ์ดํ ์งํ๋๋ j์ ์ฆ๊ฐ ์ฐ์ฐ์ ๋ชจ๋ ์๋ฏธ๊ฐ ์์ด์ง๋ค.
๋ํ ์ฌ๊ธฐ์ i์ ๊ฐ์ 1 ์ฆ๊ฐ์ํค๋ฉด arr[4] + arr[6] = 15 > 13์ด๋ฏ๋ก, ์ดํ ์งํ๋๋ i์ ์ฆ๊ฐ ์ฐ์ฐ ๋ํ ์๋ฏธ๊ฐ ์์ด์ง๋ค.
์ฆ, arr[i] + arr[j] > 13์ด๋ผ๋ฉด i์ j๋ฅผ ๋ ์ด์ ์ฆ๊ฐ์ํฌ ํ์๊ฐ ์๋ค.
์ด์ ํฌํฌ์ธํฐ ์ ํ์ ์ดํด๋ณด์!
ํฌ์ธํฐ 2๊ฐ๊ฐ ์๋์์ ๋ฐ๋๋ก ์งํํด ๋์๊ฐ๋ ๋ฐฉ์
leftPointer๋ ๊ฐ์ฅ ์ผ์ชฝ ๋์, rightPointer๋ ๊ฐ์ฅ ์ค๋ฅธ์ชฝ ๋์ ๊ฐ๋ฆฌํค๋๋ก ํ์.
1. leftPointer์ ์ธ๋ฑ์ค = 0, rightPointer์ ์ธ๋ฑ์ค = 9

arr[0] + arr[9] = 18 > 13์ด๋ฏ๋ก, ๋ ํฉ์ ๊ฐ์์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
๋ ํฉ์ ๊ฐ์์์ผ์ผ ํ๋ ์ํฉ์์๋ rightPointer๋ฅผ ๊ฐ์์ํจ๋ค.
์๋? ๋ ํฉ์ 13๋ณด๋ค ํฌ๋ค.
๋ฐฐ์ด์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌ๋์ด์๊ณ , leftPointer๋ฅผ ์ฆ๊ฐ์ํค๋ ๊ฒ์ ๋ ํฉ์ ๊ฐ์์ํค๋ ๊ฒ์ด ์๋๋ผ ์ฆ๊ฐ์ํค๋ ์ ์ด ๋๋ค.
๊ทธ๋์ leftPointer๋ฅผ ์ฆ๊ฐ์ํค๋ ๊ฒ์ด ์๋, rightPointer๋ฅผ ๊ฐ์์ํค๋ ๊ฒ์ด๋ค.
์ฆ, ์ฃผ์ด์ง ๋ฐฐ์ด์ ์ค๋ฆ์ฐจ์์ด๊ธฐ ๋๋ฌธ์ arr[leftPointer] + arr[rightPointer] = 13์ ๋ง์กฑ์ํค๋ rightPointer์ ํด๋นํ๋ ์์๋ ์ค์ด๋ ๋ค.
๋ฐ๋ผ์ leftPointer = 0์ผ ๋, ์ด๋ค k๊ฐ arr[0] + arr[k] > 13์ด๋ผ๋ฉด ์ดํ์ k+1, k+2, ..์ ์ธ๋ฑ์ค๋ฅผ ๊ฐ๋ ๋ฐฐ์ด์ ์์๋ ํ์ํ ํ์๊ฐ ์๋ค.
2. leftPointer์ ์ธ๋ฑ์ค = 0, rightPointer์ ์ธ๋ฑ์ค = 8

arr[0] + arr[8] = 17 > 13์ด๋ฏ๋ก, ์ด๋ฒ์๋ ๋ ํฉ์ ๊ฐ์์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
์์์์ ๋ง์ฐฌ๊ฐ์ง๋ก rightPointer๋ฅผ ๊ฐ์์ํจ๋ค.
3. leftPointer์ ์ธ๋ฑ์ค = 0, rightPointer์ ์ธ๋ฑ์ค = 7

arr[0] + arr[7] = 15 > 13์ผ๋ก, ์ด๋ฒ์๋ ๋ ํฉ์ ๊ฐ์์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
์์์์ ๋ง์ฐฌ๊ฐ์ง๋ก rightPointer๋ฅผ ๊ฐ์์ํจ๋ค.
4. leftPointer์ ์ธ๋ฑ์ค = 0, rightPointer์ ์ธ๋ฑ์ค = 6

arr[0] + arr[6] = 10 < 13์ด๋ฏ๋ก, ์ด๋ฒ์๋ ๋ ํฉ์ ์ฆ๊ฐ์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
์ด๋ฒ์๋ leftPointer๋ฅผ ์ฆ๊ฐ์ํจ๋ค.
5. leftPointer์ ์ธ๋ฑ์ค = 1, rightPointer์ ์ธ๋ฑ์ค = 6

arr[1] + arr[6] = 11 < 13์ด๋ฏ๋ก, ๋ ํฉ์ ์ฆ๊ฐ์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
leftPointer๋ฅผ ์ฆ๊ฐ์ํจ๋ค.
6. leftPointer์ ์ธ๋ฑ์ค = 2, rightPointer์ ์ธ๋ฑ์ค = 6

arr[2] + arr[6] = 12 < 13์ด๋ฏ๋ก, ๋ ํฉ์ ์ฆ๊ฐ์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
leftPointer๋ฅผ ์ฆ๊ฐ์ํจ๋ค.
7. leftPointer์ ์ธ๋ฑ์ค = 3, rightPointer์ ์ธ๋ฑ์ค = 6

arr[3] + arr[6] = 14 > 13์ด๋ฏ๋ก, ๋ ํฉ์ ๊ฐ์์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
rightPointer๋ฅผ ๊ฐ์์ํจ๋ค.
8. leftPointer์ ์ธ๋ฑ์ค = 3, rightPointer์ ์ธ๋ฑ์ค = 5

arr[3] + arr[5] = 13์ด๋ฏ๋ก, ์ ๋ต์ด๋ค.
์ด๋ฒ์๋ leftPointer๋ฅผ ์ฆ๊ฐ์์ผ๋ ๋๊ณ , rightPointer๋ฅผ ๊ฐ์์์ผ๋ ๋๋ค.
leftPointer๋ฅผ ์ฆ๊ฐ์์ผ๋ณด์.
9. leftPointer์ ์ธ๋ฑ์ค = 4, rightPointer์ ์ธ๋ฑ์ค = 5

arr[4] + arr[5] = 14 > 13์ด๋ฏ๋ก, ๋ ํฉ์ ๊ฐ์์์ผ์ผ ํ๋ ์ํฉ์ด๋ค.
์ด ๋ rightPointer๋ฅผ ๊ฐ์์ํค๋ฉด arr[4] + arr[4] = 6 + 6 = 12์ด๋ฏ๋ก, leftPointer๋ฅผ ์ฆ๊ฐ์ํจ๋ค.
10. leftPointer์ ์ธ๋ฑ์ค == rightPointer์ ์ธ๋ฑ์ค == 5

๋ ํฌ์ธํฐ์ ์ธ๋ฑ์ค๊ฐ ๊ฐ๋ค. ์ด์ ๋ ์์ ์กฐ๊ฑด์ด i < j์ด๋ฏ๋ก ํ์ ๊ณผ์ ์ ์ข ๋ฃํ๋ค.
ํฌ์ธํฐ 2๊ฐ๊ฐ ๊ฐ์ ๋ฐฉํฅ์ผ๋ก ์งํํด ๋์๊ฐ๋ ๋ฐฉ์
๋น ๋ฅธ ํฌ์ธํฐ๊ฐ ๋๋ฆฐ ํฌ์ธํฐ๋ณด๋ค ์์๋ ๋ฐฉ์์ผ๋ก, ๋น ๋ฅธ ํฌ์ธํฐ (rightPointer)๋ ํญ์ ๋๋ฆฐ ํฌ์ธํฐ (leftPointer)๋ณด๋ค ์์ ์๋ค.
๋๋ฆฐ ํฌ์ธํฐ (leftPointer)๋ ๋น ๋ฅธ ํฌ์ธํฐ (rightPointer)๋ฅผ ์ญ์ ํด์๋ ์๋๋ค.
์์ธํ ์ค๋ช ์ ์ด ๋ฌธ์ ๋ฅผ ์ฐธ๊ณ ํ๋ฉด ๋๋ค.
ํฌ ํฌ์ธํฐ ์ฝ๋
int leftPointer = 0; int rightPointer = n - 1; int answer = 0; while (leftPointer < rightPointer) { int sum = arr[leftPointer] + arr[rightPointer]; if (sum > 13) rightPointer--; else if (sum < 13) leftPointer++; else { answer++; rightPointer--; // leftPointer++; ํด๋ ๊ด์ฐฎ๋ค! } }var leftPointer = 0; var rightPointer = n - 1; var answer = 0; while (leftPointer < rightPointer) { var sum = arr[leftPointer] + arr[rightPointer]; if (sum > 13) { rightPointer -= 1 } else if (sum < 13) { leftPointer += 1 } else { answer += 1 rightPointer -= 1 // leftPointer += 1 ํด๋ ๊ด์ฐฎ๋ค! } }leftPointer, rightPointer๊ฐ ์์ชฝ์์ ๋ค๊ฐ์ค๊ณ , ์ค๊ฐ์ ๋ ํฌ์ธํฐ๊ฐ ๋ง๋๋ฉด ํ์์ ์ข ๋ฃํ๋ฏ๋ก leftPointer, rightPointer๊ฐ ์์ง์ธ ๊ฑฐ๋ฆฌ == ์ด ๋ฐฐ์ด์ ๊ธธ์ด์ด๋ค. ๋ฐ๋ผ์ ์๊ฐ ๋ณต์ก๋๋ O(N)์ด๋ค.
'Algorithm' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Algorithm] ์ฌ๊ท (0) 2023.05.05 [Algorithm] ๋์ ํฉ (0) 2023.05.04 [Algorithm] ๋ฐฑ์ค 2003 ์๋ค์ ํฉ 2 (C++) (0) 2023.05.01 [Algorithm] BFS & DFS (0) 2022.03.15 [Algorithm] ํ๋ก๊ทธ๋๋จธ์ค ์ ๊ณ ๊ฒฐ๊ณผ ๋ฐ๊ธฐ Level1 (Swift) (0) 2022.02.06