Skip to content
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

[kayden] Week 05 Solutions #448

Merged
merged 10 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions 3sum/kayden.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
class Solution:

# 해시맵
# 시간복잡도: O(N^2)
# 공간복잡도: O(N)
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
nums.sort()

check = {}
for idx, num in enumerate(nums):
check[num] = idx

answer = set()
for i in range(n-2):
if nums[i] > 0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

break
if i > 0 and nums[i] == nums[i-1]:
continue
for j in range(i + 1, n):
target = -(nums[i] + nums[j])
if not check.get(target):
continue
if j >= check[target]:
continue

answer.add((nums[i], nums[j], target))

return list(answer)

# 투포인터
# 시간복잡도: O(N^2)
# 공간복잡도: O(N)
def threeSum2(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
nums.sort()

answer = set()
for i in range(n-2):
if nums[i] > 0:
break
if i > 0 and nums[i] == nums[i-1]:
continue
l, r = i+1, n-1
while l<r:
if nums[l] + nums[r] == -nums[i]:
answer.add((nums[i], nums[l], nums[r]))
l += 1
r -= 1
Comment on lines +46 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'이렇게 하면 answer에 중복되는 triplet이 많이 쌓이고 answer를 list로 변환할 때 비효율적이지 않을까?' 싶어서 대안 코드도 써보고 검색도 해봤는데, 결과적으론 도긴개긴이었어요 ㅎㅎ

if nums[l] + nums[r] == -nums[i]:
    answer.add((nums[i], nums[l], nums[r]))
    while True:
        l += 1
        if nums[l - 1] != nums[l]:
            break
    while True:
        r -= 1
        if nums[r + 1] != nums[r]:
            break

https://stackoverflow.com/questions/62679314/algorithmic-complexity-to-convert-a-set-to-a-list-in-python

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

투포인터에서도 최적화해야 했었는데 깜빡했네요!
성능 자료도 찾아주셔서 정말 감사합니다! 👍 많이 도움이 됐습니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

도긴개긴 추가 ㅎㅎ 😂

if nums[l] + nums[r] == -nums[i]:
    while l < r and nums[l] == nums[l + 1]:
        l += 1
    while low < high and nums[r] == nums[r - 1]:
        r -= 1
    l, r = l + 1, r - 1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

읽기 편해졌네요 👏

while nums[l] == nums[l - 1] and l < r:
l += 1

while nums[r] == nums[r + 1] and l < r:
r -= 1

if nums[l] + nums[r] < -nums[i]:
l += 1

if nums[l] + nums[r] > -nums[i]:
r -= 1

return list(answer)
15 changes: 15 additions & 0 deletions best-time-to-buy-and-sell-stock/kayden.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# 시간복잡도: O(N)
# 공간복잡도: O(1)
class Solution:
def maxProfit(self, prices: List[int]) -> int:

answer = 0
cur = float(inf)
for price in prices:
if cur < price:
answer = max(answer, price - cur)

if price < cur:
cur = price

return answer
10 changes: 10 additions & 0 deletions group-anagrams/kayden.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# 시간복잡도: O(N*AlogA) A: 0<= strs[i]의 길이 <= 100
# 공간복잡도: O(N)
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
groups = {}
for anagram in strs:
key = str(sorted(anagram))
groups.setdefault(key, []).append(anagram)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setdefault 잘 배워갑니다 :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@obzva 같이 읽어보시면 도움이 될 만한 글 추천드려요.
https://www.daleseo.com/python-collections-defaultdict/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 좋은 블로그가 있네요 ^~^


return list(groups.values())
40 changes: 40 additions & 0 deletions implement-trie-prefix-tree/kayden.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Node:

def __init__(self, ending=False):
self.children = {}
self.ending = ending

# 공간복잡도: O(w*l) w: 단어 수 l: 단어의 평균 길이
class Trie:

def __init__(self):
self.head = Node(ending=True)

# 시간복잡도: O(N)
def insert(self, word: str) -> None:
node = self.head
for ch in word:
if ch not in node.children:
node.children.setdefault(ch, Node())
node = node.children[ch]
node.ending = True

# 시간복잡도: O(N)
def search(self, word: str) -> bool:
node = self.head
for ch in word:
if ch not in node.children:
return False
node = node.children[ch]

return node.ending

# 시간복잡도: O(N)
def startsWith(self, prefix: str) -> bool:
node = self.head
for ch in prefix:
if ch not in node.children:
return False
node = node.children[ch]

return True
25 changes: 25 additions & 0 deletions word-break/kayden.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 시간복잡도: O(S*W)
# S: s의 길이 300 W: worDict 각 단어의 총 길이 20*1000
# 300 * 20*1000 = 6*1e6 (600만)
Comment on lines +1 to +3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 17번째 줄의 s[idx:idx + l] == word 부분이 상수 시간이 걸린다고 보신건가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리뷰 감사합니다! s[idx:idx + l] == word 슬라이싱 과정이 wordDict 단어들의 총길이 만큼 연산된다고 판단하여 20*1000으로 하였습니다!

# 공간복잡도: O(S)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S는 주어진 문자열 s의 길이인가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 문자열의 길이 입니다!

class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
memo = {}
def dfs(idx):
if idx in memo:
return memo[idx]

if idx == len(s):
return True

for word in wordDict:
l = len(word)
if s[idx:idx + l] == word:
if dfs(idx + l):
memo[idx] = True
return True

memo[idx] = False
return False

return dfs(0)