integers가 담긴 list nums와 integer target을 입력 받고,
nums의 2개 요소 합이 target과 같아질 때,
2개 요소의 index를 담은 list를 반환한다.
2 <= nums.length <= 10^4,
-10^9 <= nums[i] <= 10^9,
-10^9 <= target <= 10^9,
Only one valid answer exists.
nums.length이다.nums[i], 요소 1개의 최댓값은 1,000,000,000 이고,target 또한 int 자료형 표현 범위 안에 있다. 이중 반복문으로 완전탐색 후 두 요소를 찾아 배열에 담아 리턴하는 방법이 먼저 떠올랐지만
nums.length 제약 조건에 아슬하게 걸릴 것 같아 nums의 각 요소의 '값: idx' pair를 Dicionary에 담고
nums를 오름차순 정렬한 list를 순회하며, 그 합이 target과 같은 2개의 요소를 찾기로 했다.
We can reduce the lookup time from O(n) to O(1) by trading space for speed.
A hash table is well suited for this purpose because it supports fast lookup in near constant time.
실제 문제를 푸는 단계에서는 시간복잡도를 줄이기 위해서 메모리를 사용하겠다는 개념을 갖고 있지는 않았다.
LeetCode Official Solution을 보면서 메모리를 사용해 시간복잡도를 낮추는 trade-off 관계를 다시 상기했다.
class Solution(object):
def twoSum(self, nums, target):
# 1. 오름차순 정렬
sortedNums = sorted(nums)
lastIdx = len(sortedNums) - 1
numsDict = {}
# 2. 딕셔너리에 nums 요소의 값: 인덱스 쌍을 순차적으로 추가
for idx in range(lastIdx + 1):
numsDict[nums[idx]] = idx
# 3. nums[len-1] 부터 target 보다 작은 값을 찾고,
# 해당하는 값의 idx를 lastIdx에 할당
for idx in range(lastIdx, 0, -1):
if sortedNums[idx] < target:
lastIdx = idx
break
# 4. lastIdx가 0 보다 크면
if lastIdx > 0:
for idx in range(lastIdx):
maximum = sortedNums[lastIdx]
curEl = sortedNums[idx]
curVal = target - maximum
# target - nums[lastIdx] 에 해당하는 수가 있다면
# numsDic에 저장된 원래의 idx를 list에 담아 리턴
if curEl == curVal:
origin1 = numsDict[curEl]
origin2 = numsDict[maximum]
return [origin1, origin2]
# 없다면 lastIdx를 하나 줄인다.
lastIdx = lastIdx - 1
return
nums의 요소 중 최댓값이면서 target 보다는 작은 수의 index를 lastIdx로 두고,class Solution(object):
def twoSum(self, nums, target):
# Hash table로 사용할 dict 미리 선언
hashmap = {}
# nums 순회
for i in range(len(nums)):
# target - 현재 조회중인 값이 Hash table에 있다면
# 해당 idx와 현재 조회중인 idx를 list에 담아 리턴한다.
complement = target - nums[i]
if complement in hashmap:
return [hashmap[complement], i]
# (찾고 있는 값이 Hash table에 없었다면)
# 현재 조회중인 값을 key, idx를 value로 추가한다.
hashmap[nums[i]] = i
nums의 요소를 순회하며 Hash table에 data를 넣으면서,Reference: https://leetcode.com/problems/two-sum/solutions/127810/two-sum/