[PCCP] 시간복잡도 - 두 수의 합 | 파이썬

SangJin Ham·2023년 6월 27일
0
post-thumbnail

코딩테스트 역량 강화 교육(거점형 특화 프로그램)이라는 프로그램에 참여해 공부한 내용입니다.


두수의 합

앞서 시간복잡도에 대해 학습했으니 시간복잡도를 고려해 다양하게 두 수의 합 문제를 풀어보겠다.


문제

정수 수열 안에서 수열의 원소 두 개의 합이 target값이 되는 경우를 찾고 싶습니다.
매개변수 nums에 길이가 n인 수열이 주어지고, 매개변수 target에 자연수 값이 주어지면 이 수열안에서 두 개의 원소의 합이 정수 target값이 되는 두 원소를 구해 배열에 오름차순으로 담아 반환합니다.
두 개의 원소의 합이 target값이 되는 경우는 오직 한가지 뿐인 입력만 주어집니다. 한 원소를 두 번 더하는 것은 안됩니다. nums의 각 원소는 유일값입니다.
답이 없을 경우 [0, 0]을 반환합니다.


입출력 예

입력(nums)합(target)출력(answer)
[7, 3, 2, 13, 9, 15, 8, 11]12[3, 9]
[21, 12, 30, 15, 6, 2, 9, 19, 14]24[9, 15]
[12, 18, 5, 8, 21, 27, 22, 25, 16, 2]28[12, 16]
[11, 17, 6, 8, 21, 9, 19, 12, 25, 16, 2]26[9, 17]
[7, 5, 12, -9, -12, 22, -30, -35, -21]-14[-21, 7]
[7, 5, 12, 20]15[0, 0]

제한사항

  • nums의 길이 3 <= n <= 10,000
  • 배열 nums의 원소는 정수입니다. -10,000 <= nums[i] <= 10,000
  • -20,000 <= target <= 20,000

시간복잡도(n²)

def solution(nums, target):

    n = len(nums)

    for i in range(n):
        for j in range(n):
            if  nums[i] + nums[j] == target:
                return sorted([nums[i], nums[j]])
    return [0, 0]
    
print(solution([7, 9, 2, 13, 3, 15, 8, 11], 12))
print(solution([21, 12, 30, 15, 6, 2, 9, 19, 14], 24))
print(solution([12, 18, 5, 8, 21, 27, 22, 25, 16, 2], 28))
print(solution([11, 17, 6, 8, 21, 9, 19, 12, 25, 16, 2], 26))
print(solution([7, 5, 12, -9, -12, 22, -30, -35, -21], -14))
print(solution([7, 5, 12, 20], 15))

중첩 for문으로 구현해 시간복잡도는 O(n²)이다.


시간복잡도(nlogn)


def solution(nums, target):

    nums.sort()
    nH = {}
	
    
    for i in nums:
        if (target - i) in nH:
            return[target - i, i]
        else:
            nH[i] = 1
    return [0, 0]
    
print(solution([7, 9, 2, 13, 3, 15, 8, 11], 12))
print(solution([21, 12, 30, 15, 6, 2, 9, 19, 14], 24))
print(solution([12, 18, 5, 8, 21, 27, 22, 25, 16, 2], 28))
print(solution([11, 17, 6, 8, 21, 9, 19, 12, 25, 16, 2], 26))
print(solution([7, 5, 12, -9, -12, 22, -30, -35, -21], -14))
print(solution([7, 5, 12, 20], 15))

사전형으로 구현했고, 정렬으로 인해 시간복잡도는 O(nlogn)이다.

  • 앞서 정렬을 했기 때문에 return [target -i, i]할 때 따로 정렬할 필요 없음
  • nH[i] : 해당 x값이 존재한다는 표시

시간복잡도(n)

from collections import defaultdict
def solution(nums, target):
    
    nH = defaultdict(int)
    for x in nums:
        y = target - x
        if y in nH:
            return sorted([x, y])
        nH[x] = 1
    
    return [0, 0]
    
print(solution([7, 9, 2, 13, 3, 15, 8, 11], 12))
print(solution([21, 12, 30, 15, 6, 2, 9, 19, 14], 24))
print(solution([12, 18, 5, 8, 21, 27, 22, 25, 16, 2], 28))
print(solution([11, 17, 6, 8, 21, 9, 19, 12, 25, 16, 2], 26))
print(solution([7, 5, 12, -9, -12, 22, -30, -35, -21], -14))
print(solution([7, 5, 12, 20], 15))

defaultdict(인자) : value를 지정하지 않은 모든 keyvalue인자의 자료형으로 가짐
따라서 최초에 없는 key값을 입력해도 에러가 나지 않고, 설정된 자료형으로 모든 value 초기화

  1. nHdefaultdict(int)를 이용해 모든 key값을 0으로 초기화
  2. x + y = target이라고 했을 때 y = target - x도 만족
  3. target - x를 만족하는 y
    • 있는 경우 : return sorted([x, y])
    • 없는 경우 : 해당 x값이 존재한다는 표시로 nH[x] = 1
  4. 그렇게 원소를 돌다가 target - x를 만족하는 y를 찾지 못했다면 return [0, 0]
profile
끄적끄적

0개의 댓글