Skip to content

[suwi] Week 07 #939

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

Merged
merged 5 commits into from
Jan 24, 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
49 changes: 49 additions & 0 deletions longest-substring-without-repeating-characters/sungjinwi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""
sliding window 풀이:
알고달레 풀이 참조할 것
start부터 end까지의 부분문자열 길이가 유기적으로 변하면서 이동하여 탐색
s[end]가 set에 존재하지 않으면 s[end] set에 추가하고 ans와 대소비교로 업데이트, end + 1 -> 부분문자열 크기 증가
s[end]가 set에 존재하면 s[start] set에서 제거하고 start + 1 -> s[end]와 같은 문자가 set에 없을 때까지 부분문자열 크기 감소

TC : O(N)
문자열 한번만 순회하고 set의 조회, 추가, 삭제는 O(1)이므로
SC : O(N)
문자열 길이와 set의 크기가 비례
Comment on lines +10 to +11
Copy link
Contributor

Choose a reason for hiding this comment

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

딕셔너리 자료형도 사용하실 수 있습니다 :)
생각이 안 나시거나 바쁘시다면 아래 링크를 통해서 바로 확인해보세요
https://gist.github.com/obzva/5db9d02a3e6c97f45589dab34f0f8603

Copy link
Contributor Author

Choose a reason for hiding this comment

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

재밌는 풀이네요! 아마 혼자서 생각해내진 못했을거 같아요 덕분에 github gist의 존재도 알게 됐습니다!

"""
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
ans = 0
start, end = 0, 0
chars = set()
while end < len(s) :
if not s[end] in chars :
chars.add(s[end])
ans = max(ans, end - start + 1)
end += 1
else :
chars.remove(s[start])
start += 1
return ans

"""
기존 풀이 :
각 문자를 start로 순회하는 내부에서
새로 추가되는 end 문자와 기존 문자열을 중복검사해서 길이를 늘려나가다가 중복되면 break

TC : O(N^2)
SC : O(N)

class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
ans = 0
dp = [1] * len(s)
for start in range(len(s)):
chars = set()
for end in range(start, len(s)) :
if not s[end] in chars :
chars.add(s[end])
ans = max(ans, end - start + 1)
else :
break
return ans
"""
38 changes: 38 additions & 0 deletions number-of-islands/sungjinwi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
풀이 :
전체 매트릭스를 순회하면서 visited set에 없는 땅('1')을 만나면
dfs 함수를 통해 이어진 땅을 전부 visited에 넣고 섬 cnt += 1

matrix의 크기 m * n

TC : O(M * N)
전체 매트릭스를 순회하므로

SC : O(M * N)
set의 크기 및 dfs 호출 스택은 전체 매트릭스 크기에 비례하므로

- 주어진 grid를 직접 변경해도 되면 set를 활용하지 않고 직접 값을 바꿔서 visited를 표현할 수도 있다
"""

class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
n_rows = len(grid)
n_cols = len(grid[0])
visited = set()
def dfs(i : int, j : int) :
if i < 0 or i == n_rows or j < 0 or j == n_cols:
return
if (i, j) in visited or grid[i][j] == '0':
return
if grid[i][j] == '1' :
visited.add((i,j))
for r, c in [(i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1)]:
dfs(r, c)

cnt = 0
for i in range(n_rows):
for j in range(n_cols):
if not (i, j) in visited and grid[i][j] == '1':
dfs(i, j)
cnt +=1
return cnt
29 changes: 29 additions & 0 deletions reverse-linked-list/sungjinwi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
풀이 :
cur의 next를 tmp로 저장해놓고 cur의 next를 prv로 바꾼 후 tmp를 통해 다음 노드로 이동

링크드리스트 길이 n

TC : O(N)

SC : O(1)
prv, cur 두 개만 사용하므로 O(1)

- stack에 넣어서 reverse할 수도 있음
"""

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prv = None
cur = head
while cur :
tmp = cur.next
cur.next = prv
prv = cur
cur = tmp
return prv
44 changes: 44 additions & 0 deletions set-matrix-zeroes/sungjinwi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""

풀이 :
dfs를 이용해서 인자로 들어온 row, col부터 matrix를 순회하며 0을 찾는다
0 찾으면 column 1 증가시켜 dfs호출 후 해당 행,열을 0으로 설정 후 return
모든 matrix 순회하면 return
Comment on lines +3 to +6
Copy link
Contributor

Choose a reason for hiding this comment

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

제 생각을 말씀드리자면,

  1. 우선 dfs를 이용할 문제가 아닌 것으로 판단됩니다
  2. 설령 dfs를 사용한다고 하더라도 suwi님 풀이에 불필요한 부분이 많아 보입니다
    다른 분들 풀이를 한 번 봐보시는 걸 추천드립니다

Copy link
Contributor Author

Choose a reason for hiding this comment

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

리뷰 감사드립니다!
일단 dfs 풀이는 재귀함수의 콜스택 메모리를 고려하지 못한 상황에서 공간복잡도를 O(1)로 만드려고 생각한 풀이였습니다
콜스택 때문에 그렇지 않다는 것을 알게됐지만 개인적으로 풀이 방법이 재밌어서 그대로 제출했어요!
dfs 외의 풀이는 다른 분들 참고해서 학습하겠습니다! dfs로 푼 분은 없는거 같네요...🥲
또 혹시나 dfs풀이에서 개선할 부분이 있다면 제안해주시면 감사하겠습니다


m * n matrix

TC : O(M * N)
전체 matrix를 한번 순회하므로

SC : O(M * N)
0의 개수만큼 재귀호출스택이 쌓이는데 최악의 경우 M * N만큼 호출되므로


- 다른풀이
첫째 행과 첫째 열을 각 행렬에 대한 0여부 저장하는 flag로 사용
첫째 행과 첫째 열의 0 여부는 따로 변수 2개로 저장
공간복잡도를 O(1)로 개선할 수 있음
"""

class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
n_rows = len(matrix)
n_cols = len(matrix[0])
def dfs(row: int, col: int) -> None :
while row < n_rows :
while col < n_cols :
if matrix[row][col] == 0 :
dfs(row,col + 1)
for i in range(n_rows) :
matrix[i][col] = 0
for j in range(n_cols) :
matrix[row][j] = 0
return
col += 1
col = 0
row += 1
return
dfs(0,0)
25 changes: 25 additions & 0 deletions unique-paths/sungjinwi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
풀이 :
matrix의 0th row, 0th column을 1로 놓고
matrix의 각 칸으로 오는 방법을 계산한다
현재 칸으로 오는 방법은 왼쪽에서 또는 위쪽에서 오는 방법 뿐이므로
둘을 더한 값이 현재 칸에 오는 방법의 수이다
전체 matrix가 아닌 row 한 줄 만큼의 배열, cur를 이용하여
row에 대해 반복문을 돌고 cur의 마지막 요소를 return

matrix의 크기 m * n

TC : O(M * N)
matrix의 모든 요소를 순회하므로

SC : O(N)
cur의 크기가 n에 비례하므로
"""

class Solution:
def uniquePaths(self, m: int, n: int) -> int:
cur = [1] * n
for _ in range(1, m) :
for i in range(1, n) :
cur[i] = cur[i - 1] + cur[i]
return cur[-1]
Loading