ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Algorithm] ํˆฌ ํฌ์ธํ„ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Two Pointer Algorithm)
    Algorithm 2023. 5. 2. 01:57

    ํˆฌ ํฌ์ธํ„ฐ ๊ธฐ๋ฒ•์ด๋ž€?

    • 2๊ฐœ์˜ ํฌ์ธํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ๊ฐ์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ์›์†Œ์— ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•˜์—ฌ ์š”๊ตฌํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜
    • O(N^2)๋ฅผ O(N)์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.
    • ๋Œ€๋‹ค์ˆ˜๋Š” ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ์‚ฌ์šฉํ•œ๋‹ค. ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ O(N^2) ํƒ์ƒ‰ ์ค‘ ํ•„์š” ์—†๋Š” ์—ฐ์‚ฐ์„ ๋ฒ„๋ ค์„œ O(N)์œผ๋กœ ์ค„์ธ๋‹ค.
    • ํฌ์ธํ„ฐ์— ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•˜๋Š” ์ž‘์—…์— ๋Œ€ํ•œ ์˜ˆ์‹œ๋“ค์„ ๋‹ค์–‘ํ•˜๊ฒŒ ์ ‘ํ•ด์•ผ ํ•œ๋‹ค.

    ํˆฌ ํฌ์ธํ„ฐ ๋Œ€ํ‘œ ์œ ํ˜•

    1. ํฌ์ธํ„ฐ 2๊ฐœ๊ฐ€ ์–‘๋์—์„œ ๋ฐ˜๋Œ€๋กœ ์ง„ํ–‰ํ•ด ๋‚˜์•„๊ฐ€๋Š” ๋ฐฉ์‹
    2. ํฌ์ธํ„ฐ 2๊ฐœ๊ฐ€ ๊ฐ™์€ ๋ฐฉํ–ฅ์œผ๋กœ ์ง„ํ–‰ํ•ด ๋‚˜์•„๊ฐ€๋Š” ๋ฐฉ์‹
    3. ํฌ์ธํ„ฐ ํ•˜๋‚˜๋Š” ํ•œ์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์ง„ํ–‰ํ•˜๊ณ , ๋‹ค๋ฅธ ํฌ์ธํ„ฐ๋Š” ์–‘์ชฝ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ

    ํˆฌ ํฌ์ธํ„ฐ ๋™์ž‘ ์›๋ฆฌ

    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)์ด๋‹ค.

    ๋Œ“๊ธ€

Designed by Tistory.