two sum
문제
리스트에서 두 값을 더해 목표 값을 만들 수 있는 값의 인덱스를 반환하기
해결
이중반복문
class trialanderror:
def twoSum(self, nums, target):
for i in range(len(nums)):
for j in range(len(nums[i+1:])):
if nums[i]+nums[i+j] == target:
return(i, i+j]
이중포인터
nums = [4, 1, 9, 7, 5, 3, 16]
class Solution:
def twoSum(self, nums, target):
new_nums = [[v, i] for i, v in enumerate(nums)]
new_nums.sort(key=lambda x:x[0])
l, r = 0, len(nums)-1
while l < r :
nums_sum = new_nums[l][0]+new_nums[r][0]
if nums_sum > target:
r -= 1
elif nums_sum < target:
l += 1
else:
return [new_nums[l][1], new_nums[r][1]]
해시맵
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
memo = {}
for i, num in enumerate(nums): #[3,2,4]
needed = target - num #3
if needed in memo :
return [memo[needed], i]
memo[num] = i
알게된 점
- 이중포인터의 핵심은 포인터만 돌면서 값을 가지고와서 계산을 한다는 점인데, 여기서 핵심은 초기의 인덱스 값을 밸류값과 매치하여 저장하고 밸류를 미리 정렬해 둔다는 점이다.
nums = [4, 1, 9, 7, 5, 3, 16]
new_nums = [[v, i] for i, v in enumerate(nums)]
new_nums.sort(key=lambda x:x[0])
위 코드를 수행하면 new_nums에는 (밸류, 인덱스)가 매칭되어 저장되게 된다.
(구현 방식은 여러가지가 있겠지만..)
그리고 합이 매치되는 조합을 찾는 것이 목적이므로 최대한 적은 수의 검색을 하기 위해 left에 있을 수 있는 가장 최대의 right를 찾아서 up, down 을 따져보는 방식으로 경우의 수를 줄인다.
만약에 left가 가질 수 잇는 가장 최대의 right로도 target을 넘지 못한다면 left의 값으로는 target을 만들 수 없으므로 left 포인터를 이동하는 방식이다.
사실 합을 구하는 방식은 비슷해 보이고, 위에 밸류와 키값을 매치하는 방식을 다르게 구현해 보았다.
new_nums = list(zip(nums, range(len(nums)))
- 해시맵이란?
자바에서 해시맵(HashMap)은 키(Key)와 값(Value)의 쌍으로 데이터를 저장하는 자료구조. 해시맵은 내부적으로 해시 테이블을 사용하여 데이터를 관리하므로 검색 속도가 빠르다.
키로 인덱스를 반환해야 하는 경우에 잘 쓸 수 있음.
Leave a comment