[1. Two Sum] (알고리즘)
Hash Table
문제
Given an array of integers nums
and an integer target
, return indices of the two numbers such that they add up to target
.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9 Output: [0,1] Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6 Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6 Output: [0,1]
Constraints:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- Only one valid answer exists.
Follow-up: Can you come up with an algorithm that is less than O(n2)
time complexity?
스스로 고민
접근법
- 배열에서 두 수를 추출한 뒤에 둘을 합했을 때 타겟 넘버 값을 만들 수 있는 각 요소의 인덱스를 추출하면 된다.
- 무지성으로 하기 전에 문제를 자세히 읽지 않아 삽질한 경험이 많았기 때문에 문제를 잘 살펴 보았는데 요소에는 음수도 나올 수 있다.
- 또한 다행히 요소들간에 중복은 없다.
- 이전에 투포인터 패턴을 풀다가 다른 사람들의 방법을 보던 중 같은 문제를 해시맵을 활용해서 풀었던 게 생각나서 그걸로 결정
의사코드
- 우선 모든 값을 딕셔너리에 다 넣어준다.
- 첫 번째 요소를 뽑아서 타겟 값과 계산 후 매칭 되는게 있다면 인덱스를 반환
- 없다면 두 번째 요소로 넘어가서 계속 진행
구현 코드
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
num_dict = {}
for i, num in enumerate(nums):
complement = target - num
if complement in num_dict:
return [num_dict[complement] , i]
num_dict[num] = i
시간 복잡도와 공간 복잡도
시간 복잡도:
- 반복문이
nums
리스트의 길이인 n번 실행된다. 각 반복에서 수행되는 작업은 O(1) 시간이 걸린다. - 딕셔너리에서 특정 값을 검색하는 작업도 O(1) 시간이 소요된다. 따라서 전체적으로
twoSum()
메서드의 시간 복잡도는 O(n)다.
공간 복잡도:
num_dict
딕셔너리는 최악의 경우 n개의 숫자를 저장해야 할 수 있으므로 O(n)의 공간이 소요된다.- 나머지 변수들은 상수 개수의 메모리를 사용하므로 공간 복잡도에 영향을 주지 않는다.
- 따라서 전체적으로 공간 복잡도는 O(n)다.
회고 과정
- 이전에 다른 사람들이 어떻게 했는지 봐두었던 경험 때문에 정말 쉽게 풀었다.
- 이게 순전히 내 실력은 아직 아닌거 같다. 하지만 이렇게 계속 레고처럼 쌓다보면 분명히 발전이 있을 거 같다.
- 다른 사람코드가 기억이 나서 이렇게 문제를 풀 수 있었던 이유는 다른 사람들의 접근 방법과 코드를 이해하려고 노력해서 기억에 남았던 것 같다.
- 문제를 푸는 것도 중요하지만 다른 사람들의 코드를 보면서 배울 수 있는 점이 있는지 항상 고민해보는 게 이번에 정말 큰 도움이 되었던 것 같다.
다른 사람 코드를 보고 그 기준으로 어떤 부분을 개선 할 수 있는지 최종 회고
- 와우 버그인가? 정말 손 안 대고 코 잘풀었다.
- 첫 시도만에 이런 적이 처음이라 진짜 좋았다 🥳
- 솔직히 여태까지 시간 복잡도 위주로 봤었는데 이번에는 메모리 부분으로!
class Solution:
def twoSum(self,nums: List[int], target: int) -> List[int]:
l = len(nums)
a = [0,0]
if(l>=3):
for i in range(l-1):
for j in range(i+1,l):
x = nums[i] + nums[j]
if(target==x):
a[0] = i
a[1] = j
else:
a[0] = 0
a[1] = 1
return a
시간 복잡도:
twoSum()
메서드에서 중첩 반복문을 사용하여nums
리스트를 순회하므로 이중 반복문이 사용된다.- 첫 번째 반복문은 최대 n-1번 실행되며, 두 번째 반복문은 최대 n-1, n-2, …, 1번 실행된다. 따라서 이중 반복문의 실행 횟수는 n-1 + n-2 + … + 1 = n*(n-1)/2 이며, 이는 O(n^2) 다.
- 따라서 전체적으로
twoSum()
메서드의 시간 복잡도는 O(n^2) 다.
공간 복잡도:
- 입력된 숫자 리스트와 상수 개수의 변수 이외에 추가적인 데이터 구조를 사용하지 않는다.
- 리스트
a
는 결과를 저장하는 용도로 사용되지만, 이는 입력 크기에 상관없이 고정된 크기를 가지므로 공간 복잡도에 큰 영향을 미치지 않는다. - 따라서 전체적으로 공간 복잡도는 O(1) 다.
종합하면, 주어진 코드의 시간 복잡도는 O(n^2), 공간 복잡도는 O(1) 다.
- 음.. 속도가 별로 중요하지 않고 메모리가 매우 제한적으로 사용되어야 하는 임베디드 시스템에는 위와 같은 코드가 유용할 수 있다고 생각했다.
댓글남기기