-
-
Notifications
You must be signed in to change notification settings - Fork 245
[wozlsla] WEEK 02 solutions #1750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
""" | ||
# Intuition | ||
- | ||
|
||
# Approach | ||
index가 모두 다를것, | ||
합 = 0 -> -a = b+c | ||
중복 X -> set : dic와 다르게 가변객체 삽입 X | ||
Two Pointer -> 정렬된 배열을 활용 | ||
|
||
# Complexity | ||
- Time complexity | ||
- Brute-force : O(N^3) | ||
- Set : O(N^2) - Time Limit Exceeded (memory??) | ||
- Two Pointer : O(N^2) | ||
|
||
- Space complexity | ||
- Brute-force : O(N) | ||
- Set : O(N) | ||
- Two Pointer : O(1) | ||
""" | ||
|
||
from typing import List | ||
|
||
|
||
class Solution: | ||
def threeSum(self, nums: List[int]) -> List[List[int]]: | ||
|
||
triplets = set() | ||
nums.sort() # O(NlogN), return None | ||
|
||
for i in range(len(nums) - 2): # O(N) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 제가 파이썬 문법을 잘 몰라서 ^^;; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 인덱스의 범위가 |
||
low, high = i + 1, len(nums) - 1 | ||
|
||
while low < high: # O(N) | ||
three_sum = nums[i] + nums[low] + nums[high] | ||
|
||
if three_sum < 0: | ||
low += 1 | ||
elif three_sum > 0: | ||
high -= 1 | ||
else: | ||
triplets.add((nums[i], nums[low], nums[high])) | ||
low, high = low + 1, high - 1 | ||
|
||
return list(triplets) | ||
|
||
|
||
""" Set | ||
class Solution: | ||
def threeSum(self, nums: List[int]) -> List[List[int]]: | ||
|
||
triplets = set() | ||
|
||
for i in range(len(nums) - 2): | ||
seen = set() | ||
|
||
for j in range(i + 1, len(nums)): | ||
complement = -(nums[i] + nums[j]) | ||
|
||
if complement in seen: | ||
triplets.add(tuple(sorted([nums[i], nums[j], complement]))) | ||
|
||
seen.add(nums[j]) | ||
|
||
return list(triplets) | ||
""" | ||
|
||
""" Brute-force | ||
class Solution: | ||
def threeSum(self, nums: List[int]) -> List[List[int]]: | ||
|
||
n = len(nums) | ||
result = [] | ||
|
||
for i in range(n-2): | ||
for j in range(i+1, n-1): | ||
for k in range(j+1, n): | ||
if i != j and i != k and j != k: | ||
|
||
if nums[i] + nums[j] + nums[k] == 0: | ||
li = sorted([nums[i], nums[j], nums[k]]) | ||
|
||
if li not in result: # O(L) | ||
result.append(li) | ||
|
||
return result | ||
""" | ||
|
||
nums = [-1, 0, 1, 2, -1, -4] | ||
sol = Solution() | ||
|
||
print(sol.threeSum(nums)) | ||
# [[-1,-1,2],[-1,0,1]] | ||
|
||
# print(len({1, 1, 2})) # 2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
""" | ||
# Intuition | ||
계단 정상에 오를 수 있는 방법의 수 - 1,2 - 순열? -> X. 자리수가 일정하지 않음 | ||
|
||
# Approach | ||
접근 1) 1 or 2 로만 이동 가능 | ||
|
||
풀이 참고 | ||
- 계단을 한 번에 최대 2칸 밖에 올라갈 수 없으므로, 3번째 칸에 발을 딛기 위해서는 바로 아래 칸인 2번째 칸이나 적어도 1번째 칸에 반드시 먼저 올라와있어야 함. | ||
- 즉, n 칸에 발을 딛기위해서는 그 전에 n - 1 칸이나 n - 2 칸까지 올라와왔어야 한다. | ||
|
||
접근 2) | ||
4 -> 5 | ||
1 1 1 1 | ||
2 1 1 | ||
1 2 1 | ||
1 1 2 | ||
2 2 | ||
|
||
5 -> 8 | ||
1 1 1 1 1 | ||
2 2 1 | ||
1 2 2 | ||
2 1 2 | ||
1 1 1 2 | ||
1 1 2 1 | ||
1 2 1 1 | ||
2 1 1 1 | ||
|
||
n=5까지만 봤을 때 늘어나는 규칙이 피보나치수열과 같음. (hint) | ||
|
||
# Complexity | ||
- Time complexity | ||
- DP 1 : O(N) | ||
- DP 2 : O(N) | ||
|
||
- Recursive 1 : O(2^N) | ||
- Recursive 2 (caching): O(N) | ||
|
||
- Space complexity | ||
- DP 1 : O(N) | ||
- DP 2 : O(1) | ||
|
||
- Recursive 1 : O(N) | ||
- Recursive 2 (caching): O(N) | ||
|
||
""" | ||
|
||
|
||
# DP 2 (공간 최적화) | ||
class Solution: | ||
def climbStairs(self, n: int) -> int: | ||
|
||
if n < 3: | ||
return n | ||
|
||
pre, cur = 1, 2 | ||
|
||
for _ in range(n - 2): | ||
pre, cur = cur, pre + cur # 순서 ! | ||
|
||
return cur | ||
|
||
|
||
""" DP 1 | ||
class Solution: | ||
def climbStairs(self, n: int) -> int: | ||
|
||
dp = {1:1, 2:2} | ||
|
||
for i in range(3, n+1): | ||
dp[i] = dp[i-1] + dp[i-2] | ||
|
||
return dp[n] | ||
""" | ||
|
||
""" Memoization (재귀 + 캐싱) | ||
class Solution: | ||
def climbStairs(self, n: int) -> int: | ||
memo = {} | ||
|
||
def _climb(n): | ||
|
||
if n not in memo: | ||
if n < 3: | ||
memo[n] = n | ||
else: | ||
memo[n] = _climb(n - 1) + _climb(n - 2) | ||
|
||
return memo[n] | ||
|
||
return _climb(n) | ||
""" | ||
|
||
|
||
""" Recursive | ||
class Solution: | ||
def climbStairs(self, n: int) -> int: | ||
|
||
if n < 3: | ||
return n | ||
|
||
return self.climbStairs(n-1) + self.climbStairs(n-2) | ||
""" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
""" | ||
# Intuition | ||
<!-- Describe your first thoughts on how to solve this problem. --> | ||
# Approach | ||
<!-- Describe your approach to solving the problem. --> | ||
# Complexity | ||
- Time complexity: | ||
- Space complexity: | ||
""" | ||
|
||
|
||
# DP | ||
class Solution: | ||
def rob(self, nums: List[int]) -> int: | ||
|
||
# initialize dp array | ||
dp = [0] * (len(nums) + 1) | ||
|
||
if nums: | ||
dp[1] = nums[0] | ||
|
||
for n in range(2, len(dp)): | ||
# current house : nums[n-1] | ||
rob_current = nums[n - 1] + dp[n - 2] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오오.. dp로 풀은게 너무 흥미로워요 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nums 와 dp의 인덱스를 다르게 가져가고 있습니다! n은 dp의 인덱스이고, nums[n-1]이 현재 털 집입니다.
저번주 문제인데 같이 봐주셨네요!! 그때는 DP로 접근하는 방법으로는 스스로 못 풀어서 이번에 해설을 보며 풀이했습니다. |
||
skip_current = dp[n - 1] | ||
|
||
dp[n] = max(rob_current, skip_current) | ||
|
||
return dp[-1] | ||
|
||
|
||
""" Recursive + Memoization | ||
class Solution: | ||
def rob(self, nums: List[int]) -> int: | ||
memo = {} | ||
def dfs(start): | ||
if start in memo: | ||
return memo[start] | ||
if start >= len(nums): | ||
memo[start] = 0 | ||
else: | ||
memo[start] = max(nums[start] + dfs(start + 2), dfs(start + 1)) | ||
return memo[start] | ||
return dfs(0) | ||
""" | ||
|
||
""" Recursive | ||
class Solution: | ||
def rob(self, nums: List[int]) -> int: | ||
def dfs(start): | ||
if start >= nums(len): | ||
return 0 | ||
return max(nums[start] + dfs[start+2], dfs[start+1]) | ||
return dfs(0) | ||
""" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
""" | ||
# Intuition | ||
하나씩 순회하면서 나머지 값들을 곱함 | ||
# Approach | ||
접근 1) 원형 큐를 사용하면? | ||
현재 제외하려는 요소를 popleft()로 제거하고, 나머지 요소들의 곱을 계산한 뒤, 다시 그 요소를 append()하여 다음 반복을 위해 덱의 순서를 회전 | ||
접근 2) | ||
1 b c d --> 1 x bcd | ||
a 1 c d --> a x cd | ||
a b 1 d --> ab x d | ||
a b c 1 --> abc x 1 | ||
# Complexity | ||
- Time complexity : O(N) | ||
- Space complexity : O(N) / O(1) | ||
""" | ||
|
||
from typing import List | ||
|
||
|
||
class Solution: | ||
def productExceptSelf(self, nums: List[int]) -> List[int]: | ||
|
||
n = len(nums) | ||
res = [1] * n | ||
|
||
prefix_product = 1 | ||
for i in range(n): | ||
res[i] = prefix_product | ||
prefix_product *= nums[i] | ||
|
||
suffix_product = 1 | ||
for i in range(n - 1, -1, -1): | ||
res[i] *= suffix_product | ||
suffix_product *= nums[i] | ||
|
||
|
||
""" | ||
class Solution: | ||
def productExceptSelf(self, nums: List[int]) -> List[int]: | ||
# 중복 계산을 피하는 방법? | ||
res_1 = [1] * len(nums) | ||
res_2 = [1] * len(nums) | ||
for n in range(1, len(nums)): # [1, 1(a), 2(ab), 6(abc)] | ||
res_1[n] = res_1[n - 1] * nums[n - 1] | ||
# reverse X -> range를 반대로 | ||
for n in range(len(nums) - 1, -1, -1): # [1, 4(d), 12(cd), 24(bcd)] | ||
res_2[n] = res_2[n + 1] * nums[n + 1] | ||
res_2.reverse() | ||
return [res_1[i] * res_2[i] for i in range(len(nums))] | ||
sol = Solution() | ||
print(sol.productExceptSelf([1, 2, 3, 4])) | ||
""" | ||
|
||
|
||
""" | ||
# deque : O(N^2) | ||
from collections import deque | ||
import math | ||
class Solution: | ||
def productExceptSelf(self, nums: List[int]) -> List[int]: | ||
nums = deque(nums) | ||
result = [] | ||
for _ in range(len(nums)): # O(N) | ||
tmp = nums.popleft() | ||
result.append(math.prod(nums)) # O(N) | ||
nums.append(tmp) | ||
return result | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
접근법별로 시간복잡도, 공간복잡도를 상세히 작성해주신 내용이 너무 도움이 되었습니다 👍
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어딘지 기억은 안나지만, 이런식으로 사고하는 방식을 키워보라는 글을 봤어요..
전 문제 풀이 이전에 접근 방식이나 사고 방식이 아직 너무 어려워서.. 지푸라기라도 잡는 심정으로🥲 조금씩 생각한 것들을 풀어내는 걸 연습해보려고 해보고 있어요 ㅎ