[AL] 투 포인터 알고리즘 (+슬라이딩 윈도우) - JavaScript

JMinkyoung·2022년 1월 12일
3

Algorithm

목록 보기
8/10
post-thumbnail

일차원 배열이 주어졌을 때 연속된 구간합이 M이 되도록 하는 경우의 수를 구하는 문제가 주어진다면 가장 먼저 생각 하는 방법은 바로 이중 for문을 이용하는 방법이다.

function solution() {
  const arr = [1,3,2,2,5,7,2,6];
  const M = 9;
  let ans = 0;
  
  for(let i=0; i<arr.length; i++){  // 연속된 구간의 시작
  	let sum = arr[i];
    for(let j=i+1; j<arr.length; j++){
    	if(sum === M) ans++;
      	else if(sum > M) break;
      	else sum += arr[j];
    }
  }
  return ans;
}

위와 같은 방법으로 이중 for문을 이용하면 시간 복잡도가 O(N2)O(N^2) 이므로 배열의 크기가 커질수록 엄청 느려지게 될 것이다.. 🙄

이러한 이중 for문의 느림을 보완하기 위해서 나온 알고리즘이 바로 오늘 다룰 투 포인터(Two Pointers) 알고리즘이다!

투 포인터 알고리즘 (Two Pointers Algorithm)

투 포인터 알고리즘 (Two Pointers Algorithm)은 일차원 배열에서 두 개의 포인터의 위치를 기록하면서 처리하는 알고리즘을 의미한다.

위에서 다뤘던 예시를 가지고 투 포인터 알고리즘을 이해해보자!

알고리즘 설명

첫번째로 start, end 두개의 포인터가 배열의 0번째 원소를 가리키게 한다.

🔑 Key Point 🔑
만약 현재 구간의 합이 M(9)와 같다면 ans 값을 증가시켜주고 합이 M(9) 보다 작거나 같다면 end를 1 증가시켜주고, 합이 M(9) 보다 크다면 start를 1 증가시킨다.


위의 Key Point를 계속 적용하다보면 구간의 합이 8이 될때까지 위와 같이 end가 이동하게 된다.
여전히 M(9) 보다 작으므로 end를 1 증가시키게 되면 구간의 합이 13이 되므로 start가 1증가되어 아래와 같이 이동하게 된다.

하지만 여전히 구간의 합이 M(9)보다 크므로 start는 또 이동하게 된다.

start가 이동하다보면 이렇게 구간의 합이 M(9)와 같아지는데 이때 ans 값을 증가시켜주고 end 1 증가시켜주면 된다. 이를 코드로 나타내면 아래와 같다.

function solution() {
  const arr = [1,3,2,2,5,7,2,6];
  const M = 9;
  let ans = 0;
  let start = 0, end = 0, sum = arr[0];
  
  while(arr[start] && arr[end]){
    if(sum === M){
      ans++;
      end++;
      sum += arr[end];
    }else if(sum > M){
      sum -= arr[start];
      start++;
    }else{
      end++;
      sum += arr[end];
    }
  }
  return ans;
}

슬라이딩 윈도우 알고리즘 (Sliding Window Algorithm)

슬라이딩 윈도우 알고리즘 (Sliding Window Algorithm) 은 투 포인터 알고리즘과 매우 비슷한 개념을 가지고 있다.
투 포인터의 경우에는 두 개의 포인터가 각각 움직이지만,
슬라이딩 윈도우의 경우에는 일정한 사이즈를 가지는 윈도우를 나타내는 처음과 끝 포인터가 함께 움직인다.

만약 위에서 다뤘던 예제를 가지고 슬라이딩 윈도우를 나타낸다면 아래와 같이 움직일 것이다.
(윈도우의 사이즈는 3이라고 가정하고)

참고 자료
참고 자료

profile
Frontend Developer

0개의 댓글

관련 채용 정보