"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 문제 해결 패턴

문제 해결 패턴

2024-08-20에 게시됨
검색:936

Problem Solving Patterns

현대 소프트웨어 엔지니어링의 문제 해결에 관한 블로그 시리즈에 다시 오신 것을 환영합니다!

1부에서는 요소의 빈도를 효율적으로 계산하여 알고리즘을 최적화하는 강력한 기술인 주파수 카운터 패턴을 살펴보았습니다. 놓치셨거나 빠르게 복습하고 싶으시다면 계속하기 전에 꼭 확인해 보세요.

이 부분에서는 또 다른 필수 패턴인 멀티포인터 패턴을 살펴보겠습니다. 이 패턴은 여러 요소를 동시에 비교, 검색 또는 탐색해야 하는 시나리오를 처리할 때 매우 중요합니다. 코드의 효율성을 높이기 위해 어떻게 작동하고 어디에 적용할 수 있는지 살펴보겠습니다.

02. 멀티포인터 패턴

다중 포인터 패턴은 여러 포인터(또는 반복자)를 사용하여 배열이나 연결된 목록과 같은 데이터 구조를 탐색하는 알고리즘 설계에 사용되는 기술입니다. 단일 포인터나 루프에 의존하는 대신 이 패턴은 서로 다른 속도 또는 서로 다른 시작점에서 데이터를 이동하는 두 개 이상의 포인터를 사용합니다.

예제 문제

정렬된 정수 배열을 받아들이는 sumZero라는 함수를 작성하세요. 이 함수는 합계가 0인 첫 번째 쌍을 찾아야 합니다. 그러한 쌍이 존재하는 경우 두 값을 모두 포함하는 배열을 반환합니다. 그렇지 않으면 정의되지 않음.
를 반환합니다.

sumZero([-3,-2,-1,0,1,2,3]) //output: [-3, 3]
sumZero([-2,0,1,3]) //output: undefined
sumZero([-4, -3, -2, -1, 0, 1, 2, 5]) //output: [-2, 2]

기본 솔루션

function sumZero(arr){
    for (let i = 0; i 



시간 복잡도 - O(N^2)

다중 포인터 패턴을 사용한 솔루션

1단계: 문제 이해
**정렬된
배열에서 합이 0이 되는 두 숫자를 찾아야 합니다. 배열이 정렬되어 있으므로 이 순서를 활용하여 더 효율적으로 해를 찾을 수 있습니다.

2단계: 두 포인터 초기화
두 개의 포인터를 설정합니다. 하나(left)는 배열의 시작 부분에서 시작하고 다른 하나(right)는 끝에서 시작합니다.

예:

Array: [-4, -3, -2, -1, 0, 1, 2, 5]
Left Pointer (L): -4
Right Pointer (R): 5

3단계: 포인터 값의 합계 계산
왼쪽 및 오른쪽 포인터에 값을 추가하여 합계
를 얻습니다.

Sum = -4   5 = 1

4단계: 합계를 0과 비교

  • 합계가 0보다 큰 경우: 합계를 줄이려면 오른쪽 포인터를 왼쪽으로 한 단계 이동하세요.
Sum is 1 > 0, so move the right pointer left:

Array: [-4, -3, -2, -1, 0, 1, 2, 5]
Left Pointer (L): -4
Right Pointer (R): 2
  • 합계가 0보다 작은 경우: 합계를 늘리려면 왼쪽 포인터를 오른쪽으로 한 단계 이동하세요.
New Sum = -4   2 = -2
Sum is -2 



5단계: 프로세스 반복
포인터가 만나거나 쌍을 찾을 때까지 포인터를 계속 이동하고 합계를 계산합니다.

New Sum = -3   2 = -1
Sum is -1 



합계는 0이므로 함수는 [-2, 2]를 반환합니다.

루프가 해당 쌍을 찾지 못한 채 완료되면 정의되지 않음을 반환합니다.

최종 코드

function sumZero(arr) {
  let left = 0;                         // Initialize the left pointer at the start of the array
  let right = arr.length - 1;           // Initialize the right pointer at the end of the array

  while (left  0) {               // If the sum is greater than zero, move the right pointer left
      right--;
    } else {                            // If the sum is less than zero, move the left pointer right
      left  ;
    }
  }

  return undefined;                     // If no pair is found, return undefined
}

메모:
시간 복잡도: O(n) – 이 함수는 효율적이며 배열 크기에 따라 선형적으로 확장됩니다.
공간 복잡성: O(1) – 이 함수는 최소한의 추가 메모리를 사용합니다.

결론

멀티포인터 패턴은 정렬된 데이터 구조의 요소 검색, 비교 또는 조작과 관련된 문제를 해결하기 위한 강력한 기술입니다. 서로를 향해 이동하는 여러 포인터를 사용하면 알고리즘의 효율성을 크게 향상시켜 많은 경우 시간 복잡도를 O(n²)에서 O(n)으로 줄일 수 있습니다. 이 패턴은 다목적이며 다양한 문제에 적용할 수 있으므로 코드 성능을 최적화하기 위한 필수 전략입니다.

다음 게시물을 계속 지켜봐 주세요. 여기서는 동적 데이터 세그먼트와 관련된 문제를 해결하기 위한 또 다른 필수 도구인 슬라이딩 윈도우 패턴에 대해 알아볼 것입니다. 훨씬 더 복잡한 문제를 쉽게 해결하는 데 도움이 되는 매우 유용한 패턴입니다!

릴리스 선언문 이 글은 https://dev.to/kanishkaisuru/problem-solving-patterns-3pf8?1 에서 복제되었습니다. 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3