백준 2470번
ALGORITHM ·주어진 숫자들 중 합이 0에 가깝도록 만들 수 있는 두 숫자를 찾는 문제였습니다. 투 포인터를 이용해서 풀어야하는 문제였고, 해당 문제를 풀기 위한 순서는 아래와 같습니다.
- 주어진 숫자들을 오름차순으로 정렬하기 (-98, -15, 0, 1, 22)
- 정렬된 숫자들의 왼쪽, 오른쪽에 각각 포인터를 두기
- 각 포인터에 해당하는 값들의 합을 구하고, 현재 갖고 있는 최소값과 비교하기
- 구해진 합이 최소값보다 큰 경우, 해당 포인터의 값과 최소값 저장하기
- 구해진 합이 0보다 큰 경우(우측 포인터 값이 좌측 포인터 값보다 큰 경우), 좌측 포인터를 한 칸 내리기
- 구해진 합이 0보다 작은 경우(좌측 포인터 값이 우측 포인터 값보다 큰 경우), 우측 포인터를 한 칸 올리기
- 우측 포인터와 좌측 포인터가 만나기 전까지 위 과정을 반복하기
위의 과정을 코드로 표현하면 아래와 같은 형태가 나오게 됩니다.
const [count, values] = fs.readFileSync(filePath).toString().trim().split("\n");
const sortedValues = values
.split(" ")
.map(Number)
.sort((a, b) => a - b);
// 주어진 값들을 숫자로 만들고, 그 숫자들을 오름차순으로 정렬함
let results;
// 결과를 담을 변수
let start = 0;
// 왼쪽 포인터의 index값으로, 처음에 0으로 시작함
let end = sortedValues.length - 1;
// 오른쪽 포인터의 index값으로, 처음에 배열의 마지막부터 시작함
let min;
// 포인터의 합 중 최소값일 경우 해당 변수에 담음
let isEnd = false;
// true일 시 반복문 종료
while (!isEnd) {
const sum = sortedValues[start] + sortedValues[end];
if (!min || min > Math.abs(sum)) {
// 현재의 합이 최소값보다 작은 경우, 최소값과 결과값을 변경함
min = Math.abs(sum);
results = [sortedValues[start], sortedValues[end]];
}
// 0보다 작을 시 왼쪽 포인터를 한 칸 올리고, 0보다 클 시 오른쪽 포인터를 한 칸 내림
if (sum < 0) {
start += 1;
} else if (sum > 0) {
end -= 1;
} else {
isEnd = true;
}
if (start === end) isEnd = true;
}
const result = results.join(" ");
console.log(result);
해당 문제는 투 포인터를 이용해서 풀 수 있는 대표적인 문제였습니다. 하지만, 처음에 문제를 풀 때 포인터를 이동하기 위한 조건(합이 0보다 크거나 작을 때 해당 포인터 이동)을 제대로 설정하지 못했고, 이로 인해 허비된 시간이 많았습니다. 투 포인터를 사용하며 기본적으로 이동시키기 위한 조건이 올바르게 설정되도록 유의해야 합니다.