투 포인터의 이동 기준: 양끝 비교와 정렬 배열 병합

··설명 약 7분·작성: 해비·블로그 소개

읽기 전에 알아두면 좋아요

아래 개념이 익숙하면 본문을 바로 읽으세요. 낯선 개념만 링크에서 복습하면 됩니다.

개념과 예제는 실행하지 않아도 읽을 수 있습니다. 내 컴퓨터·터미널에서 직접 실행하는 과정은 선택 실습입니다.

과정 위치와 선택 복습 안내

과정 위치: 문자열 응용 · 알고리즘 개념

과정 위치는 이 글이 속한 묶음입니다. 이 단계의 모든 개념을 먼저 읽을 필요는 없습니다. 위에 연결한 개념 중 낯선 내용만 복습하세요. 문제의 조건·상태·갱신 순서는 익숙한 언어로 설명하면 됩니다.

JavaScript로 문법·실행 복습하기 (선택)

개념 글의 코드는 JavaScript 예시입니다. 문제 화면에서는 JavaScript·Python·Java·C++·C# 중 익숙한 언어의 함수를 작성하세요. 본문의 Node.js 입출력 예시는 로컬 실행을 위한 별도 안내입니다.

투 포인터에서는 두 위치를 움직일 기준을 어떻게 정하나요?

투 포인터는 두 위치를 따로 움직이며 이미 확인한 범위를 다시 보지 않는 방법입니다. 어느 포인터를 움직여도 되는 이유를 먼저 정해야 합니다.

Level을 소문자로 바꾼 뒤 양끝에서 안쪽으로 비교하는 두 포인터
먼저 양끝 l을 비교하고, 같으면 다음 e 쌍으로 이동합니다. 원본 보기 (새 탭)

Level은 소문자로 맞춘 뒤 양끝 l ↔ l, 다음 e ↔ e를 비교하면 회문임을 알 수 있습니다.

적용 조건·범위: 영문자만 남겨 회문을 판단하는 문제라면 필터링과 대소문자 통일을 먼저 적용합니다. 숫자를 남겨도 되는지는 문제 조건으로 결정합니다. 빈 문자열과 한 글자는 위 함수에서 true입니다.

본문 근거: C++ 표준 초안 — merge

투 포인터 개념을 표현한 일러스트 표지

이 글에서 할 일: 양끝 비교와 정렬 배열 병합에서 포인터 이동 이유를 설명합니다. 선수 지식: 배열 인덱스·반복문.

양끝 비교는 확인한 쌍을 제외합니다

아래 JavaScript 예제는 문자열의 양끝을 비교하며 회문인지 확인합니다. 코드 아래의 결과를 보면서 두 위치가 언제 안쪽으로 이동하고 비교가 언제 끝나는지 살펴보세요. 직접 실행하지 않아도 설명을 따라갈 수 있습니다.

level은 양끝 쌍이 같고 lever는 첫 쌍이 다른 회문 비교
level은 l과 e 쌍을 확인한 뒤 가운데에서 끝납니다. lever는 첫 l과 r이 달라 즉시 false입니다. 원본 보기 (새 탭)
function isPalindrome(text) {
  const s = text.toLowerCase(); // 이 예제의 입력은 ASCII 영문자
  let left = 0;
  let right = s.length - 1;
  while (left < right) {
    if (s[left] !== s[right]) return false;
    left++;
    right--;
  }
  return true;
}

console.log(isPalindrome('Level'));
console.log(isPalindrome('Lever'));

실행 결과

true
false

반복문에 들어올 때 left 바깥쪽과 right 바깥쪽의 모든 쌍은 이미 같습니다. 현재 쌍도 같다면 두 위치를 동시에 안쪽으로 옮길 수 있습니다. 하나라도 다르면 즉시 실패입니다. 두 포인터가 만나거나 지나치면 비교할 쌍이 남지 않습니다.

영문자만 남겨 회문을 판단하는 문제라면 필터링과 대소문자 통일을 먼저 적용합니다. 숫자를 남겨도 되는지는 문제 조건으로 결정합니다. 빈 문자열과 한 글자는 위 함수에서 true입니다.

내 컴퓨터에서 직접 실행하기 — 회문 비교 예제 (선택)

코드를 직접 바꿔보고 싶은 분을 위한 안내입니다. 이 과정은 방문자 자신의 컴퓨터에서 진행하며, 글을 읽기 위해 반드시 실행할 필요는 없습니다.

준비물: Node.js와 코드 편집기인 Visual Studio Code(VS Code). Node.js는 JavaScript 파일을 컴퓨터에서 실행하는 프로그램입니다. 아직 설치하지 않았다면 두 프로그램의 공식 사이트에서 설치한 뒤 진행하세요.

  1. 컴퓨터에 연습용 폴더를 하나 만들고, VS Code에서 파일 → 폴더 열기로 그 폴더를 엽니다.
  2. 그 폴더 안에 palindrome.js 파일을 만듭니다. 위의 JavaScript 예제 전체를 복사해 붙여넣고 저장하세요. 마지막 console.log 줄도 포함하며, 파일 이름 끝이 .js.txt가 되지 않도록 확인합니다.
  3. VS Code의 터미널 → 새 터미널을 선택합니다. 아래쪽에 열린 터미널은 명령어를 입력하는 창입니다. 다음 명령으로 Node.js 설치 여부를 확인합니다.
node --version

v로 시작하는 버전 번호가 나오면 실행할 수 있습니다. 명령을 찾을 수 없다는 메시지가 나오면 Node.js를 설치하고 VS Code를 완전히 닫았다가 다시 여세요.

터미널의 현재 위치가 방금 파일을 저장한 폴더인지 확인한 뒤, 다음 명령을 입력하고 Enter를 누릅니다. 이 명령은 JavaScript 파일 안이 아니라 터미널에 입력합니다.

node palindrome.js

터미널에 나온 값을 위의 실행 결과와 비교하세요. Cannot find module이 나오면 파일 이름과 저장 여부, 터미널에서 연 폴더가 같은지 확인합니다.

정렬 배열에서는 작은 쪽만 이동합니다

아래 JavaScript 예제는 정렬된 두 배열에서 현재 값을 비교해 작은 값부터 하나씩 모읍니다. 코드 아래의 결과와 표를 보면서 어느 배열의 위치가 이동하는지 살펴보세요. 직접 실행하지 않아도 설명을 따라갈 수 있습니다.

두 정렬 배열을 병합할 때 선택 값과 이동 포인터의 순서
[1,4,4]와 [2,4]를 병합하며 작은 쪽의 포인터만 이동합니다. 같은 값에서는 왼쪽부터 넣고 남은 꼬리까지 붙입니다. 원본 보기 (새 탭)
function mergeSorted(a, b) {
  let i = 0;
  let j = 0;
  const result = [];
  while (i < a.length && j < b.length) {
    if (a[i] <= b[j]) result.push(a[i++]);
    else result.push(b[j++]);
  }
  while (i < a.length) result.push(a[i++]);
  while (j < b.length) result.push(b[j++]);
  return result;
}

console.log(JSON.stringify(mergeSorted([1, 4, 4], [2, 4])));

실행 결과

[1,2,4,4,4]
정렬된 [1,4,4]와 [2,4]를 병합하는 순서
비교 선택 다음 위치
1과 2 1 i만 증가
4와 2 2 j만 증가
4와 4 왼쪽 4 i만 증가
4와 4 왼쪽 4 i만 증가
왼쪽 소진 오른쪽 꼬리 4 j 증가

각 배열의 현재 값은 그 배열에 남은 값 중 최솟값입니다. 둘 중 작은 값을 결과 뒤에 넣어도 정렬 순서가 유지됩니다. 같은 값이면 왼쪽부터 넣는 규칙을 택했으며, 두 배열의 중복값은 모두 보존합니다. 한쪽이 끝나면 다른 쪽의 꼬리도 반드시 붙입니다.

내 컴퓨터에서 직접 실행하기 — 정렬 배열 병합 예제 (선택)

코드를 직접 바꿔보고 싶은 분을 위한 안내입니다. 이 과정은 방문자 자신의 컴퓨터에서 진행하며, 글을 읽기 위해 반드시 실행할 필요는 없습니다.

준비물: Node.js와 코드 편집기인 Visual Studio Code(VS Code). Node.js는 JavaScript 파일을 컴퓨터에서 실행하는 프로그램입니다. 아직 설치하지 않았다면 두 프로그램의 공식 사이트에서 설치한 뒤 진행하세요.

  1. 컴퓨터에 연습용 폴더를 하나 만들고, VS Code에서 파일 → 폴더 열기로 그 폴더를 엽니다.
  2. 그 폴더 안에 merge.js 파일을 만듭니다. 위의 JavaScript 예제 전체를 복사해 붙여넣고 저장하세요. 마지막 console.log 줄도 포함하며, 파일 이름 끝이 .js.txt가 되지 않도록 확인합니다.
  3. VS Code의 터미널 → 새 터미널을 선택합니다. 아래쪽에 열린 터미널은 명령어를 입력하는 창입니다. 다음 명령으로 Node.js 설치 여부를 확인합니다.
node --version

v로 시작하는 버전 번호가 나오면 실행할 수 있습니다. 명령을 찾을 수 없다는 메시지가 나오면 Node.js를 설치하고 VS Code를 완전히 닫았다가 다시 여세요.

터미널의 현재 위치가 방금 파일을 저장한 폴더인지 확인한 뒤, 다음 명령을 입력하고 Enter를 누릅니다. 이 명령은 JavaScript 파일 안이 아니라 터미널에 입력합니다.

node merge.js

터미널에 나온 값을 위의 실행 결과와 비교하세요. Cannot find module이 나오면 파일 이름과 저장 여부, 터미널에서 연 폴더가 같은지 확인합니다.

교집합에서는 같을 때 양쪽을 이동합니다

교집합을 찾을 때 a[i] < b[j]라면 a의 현재 값은 b의 남은 값과 같을 수 없습니다. i만 증가합니다. 반대라면 j만 증가하고, 같으면 값을 기록한 뒤 둘 다 증가합니다.

교집합에서 비교 결과에 따른 두 포인터 이동과 중복 정책
값이 같을 때 두 위치를 함께 옮깁니다. 매번 기록하면 [1,1], 중복을 건너뛰면 집합 교집합 [1]이 됩니다. 원본 보기 (새 탭)

중복 정책은 별도입니다. [1,1,2]와 [1,1,3]에서 같은 값을 매번 기록하면 [1,1]이라는 다중집합 교집합입니다. 값 하나씩만 필요한 집합 교집합이라면 같은 값의 구간을 건너뛰거나 마지막 출력값과 중복되는지 확인합니다.

두 배열 길이가 N, M이면 병합과 교집합 순회는 O(N+M) 시간입니다. 병합 결과는 O(N+M) 공간을 씁니다. 정렬되지 않았다면 비교 정렬 비용 O(N log N + M log M)을 별도로 고려합니다. 회문 비교는 O(N) 시간이며, 위 코드는 소문자 문자열을 만들어 O(N) 공간을 사용합니다.

직접 확인하고 문제에 적용하기

병합 함수에 빈 배열과 [2,2]를 넣으면 무엇이 나와야 할까요? 같은 값일 때 두 포인터를 모두 움직이면 병합 결과가 어떻게 달라질까요?

빈 배열과 2·2 배열을 병합하는 자기 확인 문제
빈 입력의 병합 결과와 같은 값에서 두 포인터를 함께 옮길 때의 영향을 직접 생각해 보세요. 원본 보기 (새 탭)
답과 이유 확인

결과는 [2,2]입니다. 병합에서 같은 값이라고 두 포인터를 함께 움직이면 원소 하나가 빠질 수 있습니다. 교집합의 이동 규칙과 구분하세요.

참고 자료

자료 확인일: 2026년 10월 19일.

이 글이 도움이 되었나요?

조회 중

이어서 공부하기

체크포인트: 예제의 상태 변화를 손으로 추적하고 아래 문제에 적용하세요. 값이 없는 경우와 원소 하나인 경우도 설명해 보세요. 전처리할 문자와 비교할 문자를 구분하고 마지막 문자·마지막 묶음을 확인하세요.

이 개념으로 더 풀어보기

다음 추천 · 이 개념으로 풀 문제: 회문 문자열 풀이: 양끝 비교로 대소문자 없이 판별하기

같은 주제의 문제에 적용하며 방금 배운 개념을 확인합니다.

권장 순서는 학습 가이드와 같습니다. 다른 순서는 접힌 참고 목록에서 확인할 수 있습니다. 읽음 표시는 숙달이나 채점 결과가 아닙니다.

원래 과정 목록 순서 (선택)

읽음 기록

읽음 — / 전체 30개 · 필수 0개

이 글을 쓴 해비

웹사이트를 제작·운영하고, 개인 서비스와 자동화·AI 도구를 만듭니다. 직접 만들며 배운 내용과 문제 해결 과정을 BlogFlow에 기록합니다.

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기