Skip to content
Open
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/liza0525.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 7기 풀이
# 시간 복잡도: O(n)
# - 슬라이딩 윈도우 기법을 사용, s의 길이 n에 비례
# 공간 복잡도: O(min(n, k))
# - 중복 문자를 저장 및 체크할 char_set의 최대 크기인 k(s의 모든 문자가 중복하지 않을 때)와 s의 크기 n 중 작은 쪽
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
max_len = 0
left = 0 # 왼쪽 포인터 지정
char_set = set() # 중복 문자 체크를 위한 set 추가

# right를 하나씩 옮겨가며 문자열 길이를 체크,
for right in range(len(s)):
while s[right] in char_set:
# 중복 문자가 생길 경우 left를 움직이되, 중복된 문자 이전의 모든 문자를 제한다.
char_set.remove(s[left])
left += 1

char_set.add(s[right]) # 현재의 문자인 s[right]를 char_set에 저장하여 다음 루프에 중복 체크를 하도록 한다.
max_len = max(max_len, right - left + 1) # 현재까지의 가장 긴 문자열을 계산하여 max_len 업데이트

return max_len
34 changes: 34 additions & 0 deletions number-of-islands/liza0525.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 7기 풀이
# 시간 복잡도: O(n * m)
# - grid의 크기 n * m 에 따라 시간 복잡도가 정해짐(최악은 모든 grid 인덱스를 다 돌 때)
# 공간 복잡도: O(n * m)
# - 재귀 호출 스택의 최대 크기는 grid 이차 배열의 크기와 동일
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
len_i, len_j = len(grid), len(grid[0])
directions = [(1, 0), (-1, 0), (0, -1), (0 , 1)] # 탐색 방향(위, 아래, 왼쪽, 오른쪽 순)

res = 0

def dfs(i, j):
grid[i][j] = "0" # 방문을 했으면 grid의 값을 "0"으로 변경해 다음 탐색 시 다시 방문하지 않도록 함
for dir_i, dir_j in directions:
next_i, next_j = i + dir_i, j + dir_j

# 다음 탐색 인덱스가 배열 범위 내이면서
# grid[next_i][next_j]가 "1"이어야 그 다음 방문을 할 수 있다.
if (
0 <= next_i < len_i
and 0 <= next_j < len_j
and grid[next_i][next_j] == "1"
):
dfs(next_i, next_j)

for i in range(len_i):
for j in range(len_j):
if grid[i][j] == "0": # grid가 "0"일 땐 섬이 아니므로 탐색하지 않는다.
continue
dfs(i, j) # 섬 찾기
res += 1 # 섬을 다 찾은 후엔 res에 1을 추가한다.

return res
28 changes: 28 additions & 0 deletions reverse-linked-list/liza0525.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,31 @@ def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
curr_node.next = pre_node
pre_node, curr_node = curr_node, temp
return pre_node


# 7기 풀이
# 시간 복잡도: O(n)
# - 링크드 리스트의 길이만큼 탐색
# 공간 복잡도: O(1)
# - 결과 변수 이외에는 curr_node 변수만 사용
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
prev_node, curr_node = None, head

while curr_node:
# next를 먼저 저장해두지 않으면 링크를 끊은 뒤 다음 노드를 잃어리므로 temp에 저장
temp = curr_node.next

# curr_node의 다음 노드로 prev_node를 저장
curr_node.next = prev_node

# prev_node와 curr_node에 각각 curr_node와 temp 노드를 저장하여 순서 바꾸기
prev_node, curr_node = curr_node, temp

return prev_node

# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
16 changes: 16 additions & 0 deletions unique-paths/liza0525.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 7기 풀이
# 시간 복잡도: O(m * n)
# - m과 n 만큼의 이중 루프를 돌게 됨
# 공간 복잡도: O(m)
# - dp의 결과 값을 저장할 배열의 길이는 m의 길이에 좌우됨
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
# 이전 열의 값만 필요로 하기 때문에 1차원 배열을 사용하며 in-place 업데이트를 하면 된다.
dp = [1 for _ in range(m)]

for _ in range(n - 1):
for i in range(1, m):
# 현재 칸 = 위에서 오는 경로 수(갱신 전 dp[i]) + 왼쪽에서 오는 경로 수(dp[i-1])
dp[i] = dp[i] + dp[i - 1]

return dp[m - 1] # 모든 루프를 돌고 나면 도착지 도달 가능 방법수가 저장이 되어 있다.
Loading