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

[bhyun-kim, 김병현] Week 5 Solutions #103

Merged
merged 1 commit into from
May 31, 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
83 changes: 83 additions & 0 deletions 3sum/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""
15. 3Sum
https://leetcode.com/problems/3sum/description/

Solution:
- Sort the list
- Iterate through the list
- For each element, find the two elements that sum up to -element
- Use two pointers to find the two elements
- Skip the element if it is the same as the previous element
- Skip the two elements if they are the same as the previous two elements
- Add the set to the output list

Example:
-----------------------------------------
low : |
high: |
i : |
[-4,-1,-1,0,1,2]

-----------------------------------------
low : |
high: |
i : |
[-4,-1,-1,0,1,2]

... no possible set with i=-4, and high=2

-----------------------------------------
low : |
high: |
i : |
[-4,-1,-1,0,1,2]


Time complexity: O(n^2)
- O(nlogn) for sorting
- O(n^2) for iterating through the list and finding the two elements
- Total: O(n^2)
Space complexity: O(n)
- O(n) for the output list
- O(n) for the prevs dictionary
- O(n) for the prevs_n set
- Total: O(n)
"""


from typing import List


class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums = sorted(nums)
output = []
prevs = dict()
prevs_n = set()

for i in range(len(nums) - 2):
n_i = nums[i]

if n_i in prevs_n:
continue
else:
prevs_n.add(n_i)

low, high = i + 1, len(nums) - 1
while low < high:
n_low = nums[low]
n_high = nums[high]
if n_i + n_low + n_high == 0:
if not f"[{n_i},{n_low},{n_high}]" in prevs:
prevs[f"[{n_i},{n_low},{n_high}]"] = 1
output.append([n_i, n_low, n_high])
Comment on lines +71 to +73
Copy link
Contributor

Choose a reason for hiding this comment

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

dictionary 말고 set 자료 구조를 쓰셨다면 좀 더 깔끔하게 중복 체크가 되지 않았을까요?
list 대신에 tuple을 사용하시면 set에 저장할 수 있거든요.

low += 1
high -= 1

elif n_i + n_low + n_high < 0:
low += 1

elif n_i + n_low + n_high > 0:
high -= 1

return output
34 changes: 34 additions & 0 deletions encode-and-decode-strings/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""
271. Encode and Decode Strings
https://leetcode.com/problems/encode-and-decode-strings/description/

Solution:
- Concatenate the strings with a special character
- Split the string by the special character

Time complexity: O(n)
- Concatenating the strings: O(n)
- Splitting the string: O(n)
- Total: O(n)

Space complexity: O(n)
- Storing the output: O(n)
- Total: O(n)
"""
from typing import List


class Codec:
def encode(self, strs: List[str]) -> str:
"""Encodes a list of strings to a single string."""
output = strs[0]

for i in range(1, len(strs)):
output += "é" + strs[i]

return output

def decode(self, s: str) -> List[str]:
"""Decodes a single string to a list of strings."""

return s.split("é")
40 changes: 40 additions & 0 deletions longest-consecutive-sequence/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
128. Longest Consecutive Sequence
https://leetcode.com/problems/longest-consecutive-sequence/description/

Solution:
- Create a set of the input list
- Iterate through the set
- For each element, find the consecutive elements
- Use a while loop to find the consecutive elements
- Update the longest length

Time complexity: O(n)
- O(n) for iterating through the set

Space complexity: O(n)
- O(n) for the set
- Total: O(n)

"""

from typing import List


class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
longest_len = 0
nums_set = set(nums)

for n in nums_set:
if n - 1 not in nums_set:
current_n = n
current_len = 1

while current_n + 1 in nums_set:
current_n += 1
current_len += 1

longest_len = max(longest_len, current_len)

return longest_len
65 changes: 65 additions & 0 deletions product-of-array-except-self/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
238. Product of Array Except Self
https://leetcode.com/problems/product-of-array-except-self/description/

Solution:
- Create two lists to store the product of elements from the left and right
- Multiply the elements from the left and right lists to get the output

Example:
nums = [4, 2, 3, 1, 7, 0, 9, 10]

left is numbers to the left of the current index
right is numbers to the right of the current index
from_left is the product of the numbers to the left of the current index
from_right is the product of the numbers to the right of the current index

i = 0: (4) 2 3 1 7 0 9 10
i = 1: 4 (2) 3 1 7 0 9 10
i = 2: 4 2 (3) 1 7 0 9 10
i = 3: 4 2 3 (1) 7 0 9 10
i = 4: 4 2 3 1 (7) 0 9 10
i = 5: 4 2 3 1 7 (0) 9 10
i = 6: 4 2 3 1 7 0 (9) 10
i = 7: 4 2 3 1 7 0 9 (10)

from_left = [0, 4, 8, 24, 24, 168, 0, 0]
from_right = [0, 0, 0, 0, 0, 90, 10, 0]
output = [0, 0, 0, 0, 0, 15120, 0, 0]
Comment on lines +5 to +28
Copy link
Contributor

Choose a reason for hiding this comment

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

설명과 시각화 좋네요 👍


Time complexity: O(n)
- Calculating the product of the elements from the left: O(n)
- Calculating the product of the elements from the right: O(n)
- Calculating the output: O(n)
- Total: O(n)

Space complexity: O(n)
- Storing the product of the elements from the left: O(n)
- Storing the product of the elements from the right: O(n)
- Storing the output: O(n)
"""
from typing import List


class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
output = [0] * len(nums)

from_left = [0] * (len(nums))
from_right = [0] * (len(nums))

from_left[0] = nums[0]
from_right[-1] = nums[-1]

for i in range(1, len(nums) - 1):
from_left[i] = from_left[i - 1] * nums[i]

for i in reversed(range(1, len(nums) - 1)):
from_right[i] = from_right[i + 1] * nums[i]

output[0] = from_right[1]
output[-1] = from_left[-2]
for i in range(1, len(nums) - 1):
output[i] = from_left[i - 1] * from_right[i + 1]

return output
43 changes: 43 additions & 0 deletions top-k-frequent-elements/bhyun-kim.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
347. Top K Frequent Elements
https://leetcode.com/problems/top-k-frequent-elements/description/

Solution:
- Count the frequency of each element in the list
- Sort the dictionary by the frequency in descending order
- Return the first k elements in the sorted dictionary

Time complexity: O(nlogn)
- Counting the frequency of each element: O(n)
- Sorting the dictionary: O(nlogn)
- Returning the first k elements: O(k)
k <= n
- Total: O(nlogn)

Space complexity: O(n)
- Storing the frequency of each element: O(n)
- Storing the sorted dictionary: O(n)
- Storing the output: O(k)
k <= n
"""
from collections import OrderedDict
Copy link
Contributor

@SamTheKorean SamTheKorean May 30, 2024

Choose a reason for hiding this comment

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

혹시 sort메서드를 사용하는데 OrderDict을 사용한 이유가 있을까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

처음 접근할 때 OrderedDict()이 아니면 sorted 를 못쓰는 줄 알고 그렇게 작성했었어요. 그냥 dict()로 바꿔도 잘 실행되네요! 감사합니다.

Copy link
Contributor

@DaleSeo DaleSeo May 31, 2024

Choose a reason for hiding this comment

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

참고로 OrderedDict에서 Ordered의 의미는 데이터를 사전에 추가한 순서 그대로 저장해준다는 의미입니다. 즉, 오름차순/내림차순 정렬과는 아무 관련이 없습니다.

Copy link
Contributor

Choose a reason for hiding this comment

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

orderdict을 잘 몰랐는데 설명 감사드립니다!

from typing import List


class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
n_dict = OrderedDict()

for n in nums:
if n in n_dict:
n_dict[n] += 1
else:
n_dict[n] = 1

n_dict = sorted(n_dict.items(), key=lambda x: x[1], reverse=True)

output = [0] * k
for i in range(k):
output[i] = n_dict[i][0]

return output