# 09. 세 수의 합(leetcode: 15)

{% embed url="<https://leetcode.com/problems/3sum/>" %}

[문제링크](https://leetcode.com/problems/3sum/)

## 문제 분석

숫자의 배열이 주어졌을 때 세 수의 합이 0이 되는 값들을 배열로 묶어서 리턴하는 문제. 0이 되는 묶음이 여러개 존재할 수 있다.

값의 합이나 뺄셈을 통해서 특정한 값을 찾을 때는 **정렬을 이용해서 푸는게 가장 쉬운 방법이다.** 따라서 이 문제도 주어진 배열을 정렬을 하자.

이후에는 투포인터을 조금 응용해서 포인터 하나를 시작점에 두고 left, right 포인터로 범위를 줄여 나가면서 문제를 풀이하면 된다.

## 풀이

```javascript
var threeSum = function(nums) {
  let ret = [];
  // 정렬. 오름차순으로 정렬하자 화살표함수의 내용물이 한줄이면 평가된 값이 그대로 리턴된다.
  nums.sort((a, b) => a - b);
  // 정답의 조건은 세 수의 배열이므로 3개의 수가 되지 않는 크기면 바로 종료
  for (let i = 0; i < nums.length - 2; i++) {
    // 중복된 값 제거
    if (i > 0 && nums[i] == nums[i - 1])
      continue;
    // 두 개의 포인터를 만든다. 앞으로 이 포인터의 간격을 줄이면 된다.
    let left = i + 1;
    let right = nums.length - 1;

    while (left < right) {
      let sum = nums[i] + nums[left] + nums[right]
      // 포인터의 간격을 줄이는 조건은 sum의 값에 따라서.
      // 이게 가능한 이유는 앞서서 정렬을 했기 때문
      if (sum > 0) {
        right -= 1;
      } else if (sum < 0) {
        left += 1;
      } else {
        ret.push([nums[i], nums[left], nums[right]]);
        // 여기서도 중복된 값 제거
        while (left < right && nums[left] == nums[left + 1]) {
          left += 1;
        }
        while (left < right && nums[right] == nums[right - 1]) {
          right -= 1;
        }
        left += 1;
        right -= 1;
      }
    }
  }
  return ret;  
};
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://simian114.gitbook.io/blog/undefined/undefined-1/09.-leetcode-15.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
