Search

LEETCODE - Two Sum

카테고리
Algorithm
태그
Leetcode
게시일
2022/11/15
수정일
2024/02/24 09:41
시리즈
1 more property

Challenge

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?
Plain Text
복사

Research

Solution을 작성하기 앞서 해당 문제를 풀기 위해 Search Algorithm을 검색해서 사용할 수 있는 게 있을까 확인해 보았습니다만, 적절한 게 없었습니다. 위의 문제에서는 target이 되는 값이 나오는 배열 index를 반환하는 문제이므로 list 내의 두 개의 쌍을 찾는 문제라고 생각하였습니다. 여기서 생각해볼 수 있었던 건 itertools 였습니다.

itertools

먼저, itertools 에서 사용할 수 있는 코드 내용을 확인해보았습니다.
Function
Result Examples
product('ABCD', repeat=2)
AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)
AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)
AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2)
AA AB AC AD BB BC BD CC CD DD
위의 코드 중 두 가지를 테스트 해보았습니다.
import itertools from typing import List class Solution: def __init__(self) -> None: pass # Time Limit --------------------------------------------------------------- @staticmethod def twoSum(nums: List[int], target: int) -> List[int]: # itertools.permutations # permutations('ABCD', 2) -> AB AC AD BA BC BD CA CB CD DA DB DC for i, j in itertools.permutations((i for i in range(len(nums))), 2): if (nums[i] + nums[j]) == target: return [i, j] # Success (Not completely) --------------------------------------------------------------- @staticmethod def twoSum(nums: List[int], target: int) -> List[int]: # itertools.combinations # combinations('ABCD', 2) -> AB AC AD BC BD CD for i, j in itertools.combinations((i for i in range(len(nums))), 2): if (nums[i] + nums[j]) == target: return [i, j]
Python
복사

Permutations

permutations는 불필요한 조합(중복)까지 비교하기 때문에 불필요한 연산을 반복합니다. 따라서 Time Limit로 문제를 풀 수 없었습니다.

Combinations

combinations는 해당 문제에서 적절한 조합을 필요한 만큼 가져와 비교할 수 있도록 합니다. 단, Time Limit이거나 가끔 성공하는 케이스로 나타났습니다. 이는 결국 O(n)^2의 연산과 큰 차이가 없기 때문으로 보입니다.
O(n)^2 연산 원인
1.
O(n) : for i, j in ... 반복문
2.
O(n) : itertools로 조합 생성
단, 2번의 itertools로 조합 생성하는 부분은 반복문을 두 번 쓰는 것보다 절반 이상 계산 횟수를 감소될 수 있다고 기대됩니다.

Solution

Follow-up: Can you come up with an algorithm that is less than O(n2) time complexity?
Plain Text
복사
문제의 마지막 라인에 해당 문장이 있습니다. 위 문제를 풀기 위해 O(n)^2의 연산이 아닌 다른 방법을 만들어낼 수 있는지를 물어보고 있습니다. 여기서 다음과 같은 솔루션을 작성하였습니다.
from typing import List class Solution: def __init__(self) -> None: pass @staticmethod def twoSum(nums: List[int], target: int) -> List[int]: for i, first in enumerate(nums): _tmp = nums.copy() first = _tmp.pop(_tmp.index(first)) try: j = _tmp.index(target - first) + 1 if j: return [i, j] except ValueError as e: pass
Python
복사

Additional Solution

combinations 활용 방법이 마음에 걸려 조금 더 연구해보았을 때, 다음과 같은 방법으로도 풀이가 가능함을 확인했습니다.
import itertools from typing import List class Solution: def __init__(self) -> None: pass @staticmethod def twoSum(nums: List[int], target: int) -> List[int]: # itertools.combinations # combinations('ABCD', 2) -> AB AC AD BC BD CD for i, j in itertools.combinations(nums, 2): if (i + j) == target: a = nums.index(i) nums.pop(a) return [a, nums.index(j)+1]
Python
복사
이 방법은 combinations object를 이용하여 nums의 조합을 찾아내고, 조합이 맞을 경우 target과 비교하여 index를 찾아 반환하는 방법을 사용하였습니다. 이 방법으로 풀이할 경우 기존 Solution의 방법보다 nums.copy() 연산을 추가적으로 하지 않아도 되므로, 메모리를 보다 절약할 수 있을 것으로 보입니다.