https://leetcode.com/problems/two-sum/description/
๋ฌธ์ : int ํ์ ์ nums์ ๋ฐฐ์ด๊ณผ target์ด ์ฃผ์ด์ก์ ๋, target์ ๋ง์กฑํ๋ ๋ฐฐ์ด์ ์ธ๋ฑ์ค 2๊ฐ๋ฅผ ๋ฆฌํดํ๋ผ.(๋จ, ๊ฐ์ ์์๋ฅผ 2๋ฒ ์ด์ ์ฌ์ฉํ๋ฉด ์๋๋ค.)
2 <= nums.length <= 10^4
๐len(nums)์ ์ต๋๊ฐ 10^4์ด๋ฏ๋ก, O(N^2)=10^8์ด๋ผ ์ด์ค for๋ฌธ์ ๋ถ๊ฐํ๋ฏ๋ก O(nlogn), O(n), O(logn) ์ค์ ํ๋ ์ฌ์ฉํ ๊ฒ
(โญ์ค์) "Only one valid answer exists." ์ฆ, target์ ๋ง์กฑํ๋ ๋ค๋ฅธ ์์์์ ์กด์ฌํ์ง ์๋๋ค๋ ๊ฒ
๐ "return indices of the two numbers such that they add up to target." ๋ฌธ์ ์ ์กฐ๊ฑด๋ ํฌํจํ๋๋ฐ, ๋ฆฌํด์ ๋ฌด์ธ๊ฐ๋ฅผ ํค! ๋ด๋ฑ๊ณ ํจ์๋ฅผ ์ข
๋ฃํ๋ ๊ธฐ๋ฅ(์ ํํ๋ ํจ์๋ฅผ ํธ์ถํ ๊ณณ์ผ๋ก ๋์๊ฐ)์ ํ๊ธฐ ๋๋ฌธ
1) ๋ฐฐ์ด์ ์ธ๋ฑ์ค 2๊ฐ๋ฅผ ๋ฆฌํดํ๋ผ? -> ์ ์ด๊ฑฐ, ์กฐํฉ์ด๊ตฌ๋. ์๋ํ๋ฉด nums์์ 2๊ฐ๋ง ์ ํํด์ target์ ๋ง์กฑํ๊ธฐ๋ง ํ๋ฉด ๋๋๊น
(์ฃผ์) ๊ทธ๋ฐ๋ฐ, ๊ฒ์ํด๋ดค๋๋ ์กฐํฉ์ ์๊ฐ๋ณต์ก๋๋ O(2^N)์ด๋๊น ์ด์ค for๋ฌธ๋ณด๋ค ๋๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ ๋ถ๊ฐ
2) O(nlogn)์ด ๊ฑธ๋ฆฌ๋ ์๋ฃ๊ตฌ์กฐ๊ฐ ๋ญ๊ฐ ์์๊น? -> ํ์ด์ฌ์ sort ๋ฉ์๋(ํต ์ํธ๋ผ nlogn์ด ๊ฑธ๋ฆผ) ๊ทธ๋ฌ๋, ์ธ๋ฑ์ค๋ง ๋ฆฌํดํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ์ ๋ ฌํ ํ์ x
3) O(n): dp๋ฐ์ ์์. ์ผ๋จ top-down ๋ฐฉ์์ผ๋ก ์ ๊ทผํด๋ณด์!
dict.keys()๋ฅผ ์ฌ์ฉ)
class Solution(object):
def twoSum(self, nums, target):
# 1) Using nested loops takes O(N^2)
ans = {} # in order to access indices
start = 0
for i in range(start, len(nums)):
for j in range(start + 1, len(nums)): # to skip overlapped index i
if nums[i] + nums[j] == target:
ans[i] = nums[i]
ans[j] = nums[j]
break
start += 1 # if you can't find the answer, add 1 to i index
return list(ans.keys())
์ ์ถ์ ์ฑ๊ณตํ๋๋ฐ, ์ฌ๊ธฐ์ ๋ฌธ์ ๋ฅผ ์ ๋๋ก ๋ถ์์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ์ธ๋ฐ์๋ ๋์ ๋๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค. ๋ค๋ฅธ ์ฌ๋์ ์ฝ๋๋ฅผ ์ฐธ๊ณ ํด์ ์์ ํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.๐
class Solution(object):
def twoSum(self, nums, target):
# 1) Using nested loops takes O(N^2)
for i in range(len(nums)):
for j in range(i + 1, len(nums)): # Use i index and Add 1 to avoid overlapping with i index
if nums[i] + nums[j] == target:
return [i, j] # Utilize feature of return
return [i, j]๋ก ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค๋ฉด์ ๋ฐํํ์๋ค.๐ค์ด์ ๊ด๊ฑด์, ์ด์ค for๋ฌธ์ ์ฌ์ฉํ์ง ์๊ณ , ์ค์ง ํ๋์ for๋ฌธ์ผ๋ก ์ด๋ป๊ฒ ์ฝ๋๋ฅผ ์ต์ ํ์ํฌ ์ง๊ฐ ๋ฌธ์ ๋ค.
๋๋์ฒด ์ด๋ป๊ฒ ํ๋ฉด ๋จ ํ๋์ for๋ฌธ์ผ๋ก ์ค์ฌ์ผ ํ๋์ง 3์๊ฐ ์ด์ ๊ณ ๋ฏผ์ ํ๋๋ฐ๋ ๋ชฐ๋ผ์ ํจ๋ฐฐ๋ฅผ ์ธ์ ํ๊ณ , ๊ฐ์ ๋ด์ฉ์ ๋ณธ ๋ค์ 3๋จ๊ณ ๋ถ์ ์ฐจ์์ ๊ธฐ๋ฐ์ผ๋ก ํ์ด ๊ณผ์ ์ ์์ฑํ๋ ค๊ณ ํ๋๋ฐ, ๊ฐ์๋ ์คํ๋ ค O(2^N)์ ๊ฐ์ง๋ ์กฐํฉ ๋ฐฑํธ๋ํน์ผ๋ก ๊ตฌํํ๊ธฐ ๋๋ฌธ์ ๋์์ด ์๋ฌ๋ค.
๋ฐ๋ผ์, ์ฐ์ ๋ณด์๊ฐ ๋ฌด์์ธ์ง, ๋์ ๋๋ฆฌ ์๋ฃ๊ตฌ์กฐ๊ฐ ๋ฌด์์ธ์ง ๊ณต๋ถํ ๋ค์, ๋๋์ฒด ๋ณด์ ์ ๊ทผ ๋ฐฉ์์ด ์ด๋ป๊ฒ ๋์ ๋๋ฆฌ ์๋ฃ๊ตฌ์กฐ๋ก ํ์ฉ์ด ๋ฌ๋์ง์ ๋ํด ๋ถ์ํ ๊ฒ์ด๋ค.
์ปดํจํฐ๋ 1๊ณผ 0์ผ๋ก๋ง ๊ตฌ์ฑ๋ bit(binary digit)๋ก ์๋ฅผ ํํํ๋๋ฐ AND, OR, ๊ทธ๋ฆฌ๊ณ XOR ์ฐ์ฐ์ ํ์ฌ ๊ฒฐ๊ณผ๊ฐ์ ์ฐ์ถํด๋ธ๋ค.
์ด ๊ณผ์ ์์ ์์๋ฅผ ํํํ๊ฑฐ๋, ์์ ์ฐ์ฐ์ ํ ๋ ๋ณด์๋ผ๋ ๊ฐ๋ ์ ์ฌ์ฉํ๋ค.
2์ง๋ฒ์ผ๋ก ์๋ฅผ ํํํ ๋, ๊ฐ์ฅ ์ผ์ชฝ๊ฐ์ธ MSB(Most Significant Bit)์ 1๋ก ์ค์ ํ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
์์ + ์์, ์์ + ์์์ ๊ฐ์ด MSB๊ฐ ๋์ผํ ๊ฒฝ์ฐ์๋ ์ฐ์ฐ์ด ์ด๋ ต์ง ์๋ค. ๊ทธ๋ฌ๋, MSB๊ฐ ์๋ก ๋ค๋ฅผ ๊ฒฝ์ฐ์๋ ์ปดํจํฐ๊ฐ ๋ฌด์์ ๋จผ์ ์ฐ์ฐ์ ํด์ผํ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ด๋ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ณด์๋ผ๋ ๊ฐ๋ ์ด๋ค.
์ด๋ค ์์ ๋ณด์: ์ด๋ค ์๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ ๋ณด์ถฉ๋์ด์ผ ํ๋ ์๋ฅผ ์๋ฏธํ๋๋ฐ, ์ปดํจํฐ๋ ๋บ์
์ ํ์ง ๋ชปํ๊ณ ๋ง์
์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ
๐ข์ด๋ ต๊ฒ ์๊ฐํ์ง ๋ง๊ณ , m์ ๋ํ n์ ๋ณด์๋ m์ ๊ธฐ์ค๊ฐ์ผ๋ก ํด์ m = n + x, ๊ทธ๋ฌ๋๊น "n์ ์ด๋ค ์๋ฅผ ๋ํ๋ฉด m์ด ๋ ๊น์?" ๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค.
๐๊ทธ๋์ m = n + x => x = m - n => x = m + (-n)
์) 9 - 6 = 3 -> 9 + (-6) = 3
9์ ๋ํ 6์ ๋ณด์๋ 3, ๊ทธ๋ฌ๋๊น 9๋ฅผ ๊ธฐ์ค๊ฐ์ผ๋ก ํ์ ๋ "6์ ์ด๋ค ์๋ฅผ ๋ํ๋ฉด 9๊ฐ ๋ ๊น์?" ๋ต์ 3
์ด๋ ๊ฒ ๋ณด๋ฉด, ๋ณด์๋ฅผ ํตํด ์ฒ๋ฆฌํ๋ ๊ธฐ๋ฒ์ ๋บ์
์ binary operator๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ์๋๋ผ unary operator๋ก ์ฌ์ฉํจ์ ์ ์ ์๋ค.
์) a - b โ a + (-b)
a์ ๋ํ b์ ๋ณด์, ๊ทธ๋ฌ๋๊น a๋ฅผ ๊ธฐ์ค๊ฐ์ผ๋ก ํ๊ณ , "b์ ์ด๋ค ์๋ฅผ ๋ํ๋ฉด a๊ฐ ๋ ๊น์?" ๋ต์ a-b
... ์์ ๊ท๋ฉ์ ์ถ๋ก ์ ์ ์ฉํ์ ๋, ๋ณด์๋ผ๋ ๊ฐ๋ ์ ๊ฒฐ๊ตญ "์ด๋ ํ ๊ธฐ์ค๊ฐ์ ๋ํ์ฌ ์ด๋ค ์์ ๋ฌด์์ ๋ํ๋ฉด ๊ธฐ์ค๊ฐ์ด ๋ ๊น์?"๋ผ๋ ๋ง์ ์ง๋์ง ์๋๋ค.
๐๋ค์ ๋ฌธ์ ๋ก ๋์์ค๋ฉด, num + x = target์ด ๋์ด์ผํ๋๋ฐ, ์ด๋ ๋ณด์์ ๊ฐ๋
์ ์ฌ์ฉํด์ "num์ ์ด๋ค ์๋ฅผ ๋ํ๋ฉด target์ด ๋ ๊น์?" ์ฆ, target = num + x๊ฐ ๋๋ค.
์ด๊ฒ์ x์ ๋ํ ์์ผ๋ก ๋ํ๋ด๋ฉด, x = target - num์ด ๋๋ค.
๋น ๋ฅธ ํ์์ ์ํ ์๋ฃ๊ตฌ์กฐ๋ก์ key-value ์์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅ๋ฐ๋๋ค.

๐ข์ฝ์ , ์ญ์ , ๊ฒ์์ ์๊ฐ๋ณต์ก๋๋ ๋ชจ๋ O(1)์ด๋ค!!
๋จผ์ ๋์ ๋๋ฆฌ๊ฐ ์ ์ถํํ๋์ง๋ฅผ ์๊ธฐ ์ํด์๋, ์ง์ ์ฃผ์ํ ํ ์ด๋ธ์ด๋ผ๋ ๊ฐ๋ ์ ๋จผ์ ์์์ผ ํ๋ค. ์ฝ๊ฒ ์๊ฐํ๋ฉด ๋ฆฌ์คํธ(๋๋ ๋ฐฐ์ด)์ ์ธ๋ฑ์ค๋ฅผ key ๊ฐ์ผ๋ก ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ key ์์น์ ์ ์ฅํ๋ ๋ฐฉ์์ ๋งํ๋ค.
๐์ง์ ์ฃผ์ํ ํ
์ด๋ธ์ ๋ฌธ์ ์
1. ๋ถํ์ํ ๊ณต๊ฐ ๋ญ๋น
๐๋ฐ๋ผ์, ์ง์ ์ฃผ์ํ ํ ์ด๋ธ์ ๋์์ผ๋ก, h(k)๋ฅผ index๋ก ์ฌ์ฉํด์ {key: value} ๋ฐ์ดํฐ ์์ ์ ์ฅํ๋ ๋ฐฉ์์ด ๋์ ๋๋ฆฌ(ํด์ํ ์ด๋ธ) ์๋ฃ๊ตฌ์กฐ๋ค.
๋ชจ๋ ๋ฐ์ดํฐ์ key๊ฐ์ ๋ฌด์กฐ๊ฑด ์กด์ฌํด์ผ ํ๋ฉฐ, ์ค๋ณต๋๋ key๊ฐ์ด ์์ด์๋ ์๋ฉ๋๋ค.
๐DB์ ๊ธฐ๋ณธํค๋ฅผ ์๊ฐํ์
Collision: ์๋ก ๋ค๋ฅธ key์ ํด์๊ฐ์ด ๋๊ฐ์ ๋๋ฅผ ๋งํ๋ค.
์) h(k1) = a, h(k2) = a์ธ ๊ฒฝ์ฐ
in ์ฐ์ฐ์: ๋์ ๋๋ฆฌ์์ key๊ฐ ์กด์ฌํ๋์ง ํ์ธํด์ค
dictionary.items(): (key, value)์ ๋ชจ๋ ์ ๊ทผํ ๋ ์ฌ์ฉdictionary.keys(): dictionary์ key๋ค์ ์ ๊ทผํ ๋dictionary.values(): dictionary์ value๋ค์ ์ ๊ทผํ ๋dictionary.get(): key์ ํด๋นํ๋ value๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฌ์ฉ์, ์ด์ ๋ณด์์ ๋์ ๋๋ฆฌ ๊ฐ๋ ์ ๋ํด์ ์์๋ดค์ผ๋, Two sum ๋ฌธ์ ๋ฅผ ๋จ ํ๋์ for๋ฌธ์ ์ฌ์ฉํด์ ํ ์๊ฐ ์๋ค.
๋ฌธ์ ๊ฐ ๋ฌผ์ด๋ณด๋ ํฌ์ธํธ:
1. ๋์
๋๋ฆฌ์ key๋ฅผ ๋ฌด์์ผ๋ก ์ฌ์ฉํ๊ณ , ๋๊ฐ ๋ฌธ์ ๊ฐ ์๊ตฌํ๋ ๋ต์ด ๋ฌด์์ธ์ง ์บ์น๋ฅผ ํ๋๋, "๋ฐฐ์ด์ ์ธ๋ฑ์ค 2๊ฐ๋ฅผ ๋ฆฌํด"ํ๋ผ๋ ๊ฒ์ ๋์
๋๋ฆฌ์ value๋ก ์ฌ์ฉํ ์ ์๋์ง๋ฅผ ๋ฌผ์ด๋ณด๋ ๋ฌธ์ ์๋ค.
O(1)์ด ๊ฑธ๋ฆฌ๋ ๊ฒ์ ์๋๋๋ ๋ฌผ์ด๋ณธ๋ค.
class Solution(object):
def twoSum(self, nums, target):
num_to_index = {}
for i, num in enumerate(nums):
# ๋ณด์ ๊ฐ๋
์ฌ์ฉ
x = target - num
if x in num_to_index:
return [num_to_index[x], i]
num_to_index[num] = i
โฐ์๊ฐ๋ณต์ก๋: ๋จ ํ๋์ for๋ฌธ์ ๋ฐ์ดํฐ๊ฐ ์ํํ๋ฏ๋ก O(N)
๐์ฐธ๊ณ ์๋ฃ
๐๋ณด์: https://devraphy.tistory.com/279