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

[Chaedie] Week 7 #937

Merged
merged 6 commits into from
Jan 25, 2025
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
22 changes: 22 additions & 0 deletions longest-substring-without-repeating-characters/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""
Solution:
1) for iteration 을 도는 동안 hash set 을 이용해 처음 발견한 원소들을 window set에 넣는다.
2) 중복되는 원소를 발견할 경우 해당 원소의 중복이 사라질때까지 left side 의 원소들을 하나씩 제거한다.

Time: O(n^2) = O(n) (for iteration) * O(n) 최악의 경우 n만큼의 중복제거
Copy link
Contributor

Choose a reason for hiding this comment

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

각 문자마다 최대 2번의 연산만 실행됩니다

  • window에 추가하는 경우
  • window에서 삭제하는 경우
    그럼 시간 복잡도는 O(2N) = O(N)으로 계산되어야 할 것 같아요
    어떻게 생각하세요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

O(2N) => O(N) 이 맞는것 같습니다.
loop 내부에서 연산을 한다는 것만으로 관성적으로 곱셈으로 생각한것 같습니다. 감사합니다..!

Space: O(n) (모든 원소가 set에 들어갈 경우)
"""


class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
window = set()
Copy link
Contributor

@obzva obzva Jan 23, 2025

Choose a reason for hiding this comment

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

set으로 이미 방문한 문자들을 관리하는 대신에, dictionary로 { 방문한 문자: 해당 문자의 인덱스 }를 관리할 수도 있습니다 :)
참고하시라고 gist 남깁니다 https://gist.github.com/obzva/5db9d02a3e6c97f45589dab34f0f8603

Copy link
Contributor Author

@Chaedie Chaedie Jan 24, 2025

Choose a reason for hiding this comment

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

감사합니다.참고하겠습니다..!

max_len = 0
l = 0
for r in range(len(s)):
while s[r] in window:
window.remove(s[l])
l += 1
window.add(s[r])
max_len = max(max_len, len(window))
return max_len
31 changes: 31 additions & 0 deletions number-of-islands/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Solution:
1) for 문을 돌면서 섬(1)인 경우 result 에 1을 더하고 dfs를 돌린다.
2) dfs 를 통해 섬 전체를 순회하며 0으로 만들어준다.
3) 섬의 갯수 result 를 return 한다.

육지의 갯수 n
Time: O(n) n회의 dfs 함수 실행 될 수 있음
Space: O(n) n의 호출스택이 사용 될 수 있음
"""


class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
ROWS, COLS = len(grid), len(grid[0])
result = 0

def dfs(i, j):
if i < 0 or i >= ROWS or j < 0 or j >= COLS or grid[i][j] == "0":
return
grid[i][j] = "0"
for dx, dy in [(0, 1), (0, -1), (-1, 0), (1, 0)]:
dfs(i + dx, j + dy)

for i in range(ROWS):
for j in range(COLS):
if grid[i][j] == "1":
dfs(i, j)
result += 1

return result
21 changes: 21 additions & 0 deletions reverse-linked-list/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Solution:
1) next node를 저장합니다.
2) cur node 를 prev node 로 연결시킵니다.
3) cur node 가 prev node 가 됩니다.
4) cur node 는 next node 가 됩니다.
Time: O(n)
Space: O(1)
"""


class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev = None
cur = head
while cur:
next = cur.next
Copy link
Contributor

Choose a reason for hiding this comment

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

개인적인 생각입니다, 변수명을 next로 지으니까 좀 헷갈리는 것 같아요
지금은 간단한 함수라 괜찮지만, 더 복잡해지면 좀 어지러울 수 있을 것 같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

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

node.next 와 next 라는 변수명이 겹쳐서 헷갈린다는 의미시죠? temp 로 수정하겠습니다. 👍

cur.next = prev
prev = cur
cur = next
return prev
31 changes: 31 additions & 0 deletions set-matrix-zeroes/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Solution:
1) matrix를 순회하면서 0을 찾는다.
2) 0일 경우 rows, cols set에 각 인덱스를 넣는다.
3) rows, cols 를 순회하면서 해당하는 row, col을 0으로 만들어준다.
Time: O(nm) = O(nm) (순회) + 최대 O(nm) + 최대 O(nm)
Space: O(n + m)
"""


class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
ROWS, COLS = len(matrix), len(matrix[0])
rows = set()
cols = set()
for i in range(ROWS):
for j in range(COLS):
if matrix[i][j] == 0:
rows.add(i)
cols.add(j)

for i in rows:
for j in range(COLS):
matrix[i][j] = 0

for j in cols:
for i in range(ROWS):
matrix[i][j] = 0
33 changes: 33 additions & 0 deletions unique-paths/Chaedie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
1 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

Solution:
1) grid에서 0,0을 제외하곤 도달할 수 있는 방법이 left way + upper way 갯수밖에 없다고 생각했다.
2) 따라서 grid를 순회하며 grid index의 경계를 넘어가지 않을 경우 left way + upper way 갯수를 더해주었다.
3) 마지막 grid의 우하단의 값을 return 해주었습니다.
Time: O(mn) (원소의 갯수)
Space: O(mn) (원소의 갯수)
"""


class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = []
for i in range(m):
dp.append([0] * n)
print(dp)
Copy link
Contributor

Choose a reason for hiding this comment

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

ㅎㅎㅎ 여기 디버깅하시고 깜빡하셨어요!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

앗 ㅎㅎㅎㅎ


for i in range(m):
for j in range(n):
if i == 0 and j == 0:
dp[i][j] = 1
continue

up_value = 0 if i - 1 < 0 or i - 1 >= m else dp[i - 1][j]
left_value = 0 if j - 1 < 0 or j - 1 >= n else dp[i][j - 1]

Comment on lines +28 to +30
Copy link
Contributor

Choose a reason for hiding this comment

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

이렇게 하시는 것보다 17번 줄 근처에서 애초에 dp를 m x n 크기의 2차원 배열로 초기화시키고 시작하는게 더 깔끔할 것 같아요

Copy link
Contributor Author

Choose a reason for hiding this comment

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

감사합니다.
dp 배열 만들 때 1로 초기화 시키고, 배열 인덱스 경계 체크 없이 1부터 m, 1부터 n 계산하도록 했습니다. 리뷰 주신대로 훨씬 깔끔해졌네요 감사해요 항상 👍 (반영이 늦어서 다음 PR 에 포함될 예정입니다 🙏)

def uniquePaths(self, m: int, n: int) -> int:
        dp = [[1] * n] * m

        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

        return dp[m - 1][n - 1]

dp[i][j] = up_value + left_value

return dp[m - 1][n - 1]
Loading