최대 1 분 소요

1. 문제Permalink

15. 3Sum

Medium


Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

 

Example 1:

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]

Example 2:

Input: nums = []
Output: []

Example 3:

Input: nums = [0]
Output: []

 

Constraints:

  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

출처: Leetcode, https://leetcode.com/

2. 해결방법 시간복잡도Permalink

  1. 이분탐색 O(N^2)

3. 문제 해결 및 코드Permalink


class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# 이중 반복문을 사용하되, 처음 i값이 j, k 반복문과 달라야하며
# 3값을 더한 값이 0이여야 한다.
result = []
nums.sort()
# 이분탐색 알고리즘 사용
n = len(nums)
for i in range(n - 2):
lf = i + 1 # 좌
rf = n - 1 # 우
if i > 0 and nums[i] == nums[i - 1]: continue
while lf < rf:
tmp = nums[i] + nums[lf] + nums[rf]
# 계산해야 할 값
if tmp > 0: # 0보다 큼 -> 큰수를 당긴다.
rf -= 1
elif tmp < 0: # 0보다 작음 -> 작은수를 당긴다.
lf += 1
else:
idx = [nums[i], nums[lf], nums[rf]]
if idx not in result: result.append(idx)
# 중복되지 않은 경우(이미 리스트에 없는 경우에만 삽입)
lf += 1 # 좌에서 한칸 당기고
rf -= 1 # 우에서 한칸 당기고
return result
view raw 15.py hosted with ❤ by GitHub
  • 주석을 참고하면서 이해를 돕습니다.Permalink

4. 알고리즘 및 해설Permalink

  1. 이중 반복문을 통해 3값을 더한 값이 0인 경우를 구한다.
  2. 반복문을 통해 해당 위치 좌우칸을 동시에 비교한다. 이때 while문을 통해 탐색을 진행한다.
    • 0보다 크다면 큰 수르 당긴다.
    • 0보다 작다면 작은 수를 당긴다.
    • 0이라면 idx라는 리스트를 만들어 현재 값과 좌측값 우측값을 넣는다.
      • 이때 결과 리스트에 값이 없는 경우에만 결과값에 넣어준다.
    • 좌우값을 모두 한칸씩 당기며 재탐색한다.
  3. 위의 과정을 상위 반복문이 끝나기전까지 반복한뒤 결과값을 출력한다.