[WIL] 220124~220129_항해 3주차

박민우·2022년 1월 30일
0

항해

목록 보기
14/33


회고를 쓰는 건 한 주의 끝이라 그런 것일까?
다음 한 주를 시작하는 느낌으로 적어야 할 수 있다는 의지적인 힘이 생겨날 것 같은데 -

매주 지난주만큼이나 힘들었다고 이야기하게 되는 것 같다.
물론 힘들었는데 안 힘든 척 할 수는 없지만 말이다.

하루 하루를 곱씹어보면 가장 힘든 것이 무엇일까? 고민해보면,
말 그대로 '항해'. 바다 위를 지나는데 아직도 배멀미를 하는 것이 힘들다고 표현하는 게 적절하지 않나 싶다.
문제도 잘 풀리고, 이해도 잘 되고, 좋다! 싶을 때는 바람을 타고 잘- 나아가다가.
이해도 안 되고, 문제는 안 풀리고, 다른 사람들은 다 열심히 최선을 다해서 잘 하고 있는 것 같이 보일 때는 정말..
암초에 걸린 배처럼 답이 없다.


Algorithm(1/24 ~ 1/29)

1. 월요일

backtracking

  • 백트래킹은 dfs와 bfs의 연속이었다. 월요일은 벌써 공부했던 것이 옛날처럼 느껴진다.
  • bfs, dfs를 다시, 또 다시 계속 붙들었던 날이다. 그래서 멘탈이 나갔다. 내가 여태한 것이 이해가 하나도 되지 않은 것 같았고. 심지어 제약을 둬야하는데, 내가 제일 구현할 때 놓치는 부분이 바로 그 제약조건이어서. 약한 부분을 계속 두드려 맞는 것 같아서인지, 저녁 때는 멘탈이 많이 흔들렸었다.
  • TIL에도 멘탈 흔들린 이야기가 전부인 것 같다 -

월요일 TIL 바로가기

2. 화요일

이진트리

  • 감사하게도 하루만에 다시 정신을 차리고 공부에 집중을 했다. 많은 문제들에 대해 너무 무겁지도 않은 마음으로 계속 집중해서 들여다 보는 시간이었다.
  • 이진트리 개념 공부
  • 이진 트리의 최대 깊이(leetcode 104)
  • 이진 트리의 직경(leetcode 543)
  • 가장 긴 동일 값의 경로(leetcode 687)
  • 이진 트리의 반전(leetcode 226)
  • 트리의 부모 찾기(BOJ 11725)

화요일 TIL 바로가기

3. 수요일

이진탐색트리

  • 이진트리와 이진탐색트리는 dfs, bfs에 비하면 쉬어가는 느낌이 들었다. 그래서 문제를 붙잡고 여러모로 생각하는 시간을 가졌다. 그런데 아마, 이 쯤부터가 아니었을까. 문제를 보면 붙들고 싶다는 의지보다는 답을 보고 쉬고 싶다는 어떤 무기력감이 덮치기 시작한 것이 말이다.
  • 이진 탐색 트리 개념 공부
  • 이진 트리 활용
  • 두 이진 트리 병합(leetcode 617)
  • 이진 트리 직렬화 & 역직렬화(leetcode 297)
  • 균형 이진 트리(leetcode 110)
  • 최소 높이 트리(leetcode 310)
  • 트리(BOJ 1068)

수요일 TIL 바로가기

4. 목요일

시험

  • 시험1 : 방문 길이(programmers)
  • 시험2 : 타겟넘버(programmers)
  • 이후 개인적인 알고리즘 정리
  • 지난 주는 문제를 풀어내서 나태해졌다면, 이번에는 위에 적은 것과 같이 무기력감이 밀려온 상태에서 어떻게든 풀어내려 해보았지만 여전히 풀지 못하는 나 자신의 모습에 낙심하였다.
    당연히 실력차가 날 수 있고, 그 날 그 날에 따라 풀기도 못 풀기도 하겠지만. 요즘 같이 하던 조원들과 실력차 때문에 좀 더 무기력감을 느끼게 되는 것 같았다. 그렇게 무기력해진 상태로 정리도 제대로 되지 않은 어떠함을 가지고 목요일을 마쳤다.
  • 이후 밍글, 조원들과 이야기를 나누며 헤어짐의 시간이 있었는데.. 다시, 또 다른, 의지적인 한 걸음이 아니라 좀 더 나태해지고, 그러한 나를 보게 되고, 그러면서 불안해지는 한 걸음이 된 것 같다.

목요일 TIL 바로가기

5. 금요일

  • 새로운 조와 인사를 나누고, 어색하지만 다시 으쌰으쌰 해나가는 시간을 가지기
    (좋은 에너지와 도전도 받고, 함께 해나가려고 했는데 - 뭔가 삐끗한 것은 아닌가 돌아보게 된다)
  • 이전 조에서는 처음부터 같이 공부를 했고, 그래서 같이 성장하고, 등등의 느낌들이 있어서 마지막엔 수준 차가 나더라도 따로 또 같이 하는 것들이 가능했다. 그런데 확실히 2주간 공부를 하다가 조를 바꾸니 맞지 않는 부분들이 있었다. 그래도, 서로에게 더 도움이 되고자 하는 마음에 으쌰으쌰 하기로 했다. (마지막 토요일 회고에 적겠지만, 내가 많이 부족하다는 것을 깨닫는 것이 모두에게 도움이 되는 결정은 아니었을까 생각해보게 된다)
  • 공부의 내용은 'heap'이었고, 이는 파이썬 자체에서는 heapq라는 라이브러리를 이용해서 간단하게 처리할 수 있는 것들이 많이 있었다. 그래서 heap의 구현을 여러번 따라쳐보며 자료구조 자체에 대한 공부를 하려고 했다.
  • 그리고 내일부터 앞으로 있을 알고리즘에 대한 공부들은 지난 부분들에 비해 어려울 것 같아 예습을 시작했다.
  • heap 구현
  • heapq 이용해서 문제 풀기
  • 조원들과 함께 문제 정하여 풀기
  • sort 예습

금요일 TIL 바로가기

6. 토요일

정렬

  • 많이 무너진 하루였다. 한 주의 마지막이자, 설 연휴의 시작 즘 멘탈이 무너진 부분에 대해 굉장히 아쉽지만. 정말 이번 기회를 통해 '나의 공부' 와 앞으로 가야할 길에 대해 제대로 생각을 해봐야겠다.
  • bubble sort 구현
  • selection sort 구현
  • insertion sort 구현
  • quick sort(예습)
  • merge sort(예습)
  • leetcode 문제 (147 삽입 정렬 리스트, 발표 !)
  • 공부를 안 하거나 못한 것은 아니다. 스스로 신청한 발표까지 있었기 때문에 집중하는 시간들과 최선을 다하는 시간들이 있었다. 그런데 계속 내 눈 앞에 있는 무언가를 바라보기 싫어하는 스스로를 보았다.
    눈 앞에 문제가 있으면 답을 보고 싶고, 취업에 대한 이야기를 할 때면 갈 수 있을까라는 고민만 들고, 주특기 이야기가 나올 때면 다른 강의나 먼저 들을까- 하는 어떤 안일하고도 현실을 피하는 생각들과 태도들.
  • 내가 많이 부족하다는 것을 깨닫고 있다. 그렇다면, 조원들에게도 양해를 구하고. 제대로 쌓아나가는 것을 지금이라도 시작해야 한다. 꼭.

토요일 TIL 바로가기

DFS

DFS(Depth-First Search)는 이름에서 알 수 있듯이 그래프 전체를 탐색하는 방법(i.e., 완전 탐색) 중 하나로서 그래프에서 특히 "깊이"를 우선적으로 탐색하는 알고리즘이다. 한 노드를 시작으로 다음 분기(branch)로 넘어가기 전에 해당 분기를 완벽하게 탐색한다는 특징이 있다.

  • 그래프에서 간선이나 변수 정보를 수시로 변경해야 하는 문제는 DFS를 활용하는 것이 효과적이라는 특징이 있다.

DFS 알고리즘의 구체적인 동작 과정은 아래와 같다.

  1. 탐색 시작 노드 정보를 스택에 삽입하고 방문 처리 한다.
  2. 스택 내 최상단 노드에 방문하지 않은 노드가 있다면 그 인접 노드 정보를 스택에 삽입하고 방문 처리한다.
    만일 방문하지 않은 인접 노드가 없다면 스택 내 최상단 노드를 꺼낸다.
  3. 2번의 과정을 더 이상 수행할 수 없을 때까지 반복한다.

방문 처리란, 스택에 한 번이라도 삽입된 노드를 다시 삽입하지 않도록 체크하는 것을 의미한다.
즉, 방문 처리를 함으로써 각 노드를 한 번씩만 처리할 수 있게 한다.

DFS 구현 (python)

# DFS 메서드 정의
def dfs (graph, node, visited):
    # 해당 노드를 방문 처리
    visited[node] = True
    # 탐색 순서 출력
    print(node, end = ' ')
    # 한 노드로부터 인접한 다른 노드를 재귀적으로 방문 처리
    for i in graph[node]:
        if not visited[i]:
            dfs(graph, i, visited)
            
graph = [
    [],
    [2, 3],
    [1, 8],
    [1, 4, 5],
    [3, 5],
    [3, 4],
    [7, 8],
    [6, 8],
    [2, 6, 7]
]

# 노드별로 방문 정보를 리스트로 표현
visited = [False] * 9

# 정의한 DFS 메서드 호출(노드 1을 탐색 시작 노드로 설정)
dfs(graph, 1, visited)

실행결과
1 2 6 8 6 7 3 4 5

BFS

BFS(Breadth-First Search)란 너비 우선 탐색이라고 불리며 그래프에서 가까운 노드부터 탐색하는 알고리즘이다.

  • BFS 알고리즘은 주로 그래프에서 모든 간선의 비용이 동일한 조건에서 최단 거리를 구하는 문제를 효과적으로 해결할 수 있다. 그리고 "미로를 빠져나가는 최단 거리(경로)"를 구하는 문제 등에서 효과적으로 활용할 수 있는 알고리즘입니다.

BFS는 인접한 노드를 반복적으로 큐에 삽입하고 먼저 삽입된 노드부터 차례로 큐에서 꺼내도록 알고리즘을 작성하면 된다. BFS 알고리즘의 구체적인 동작 과정은 아래와 같다.

  1. 탐색 시작 노드 정보를 큐에 삽입하고 방문 처리 한다.
  2. 큐에서 노드를 꺼내 방문하지 않은 인접 노드 정보를 모두 큐에 삽입하고 방문 처리한다.
  3. 2번의 과정을 더 이상 수행할 수 없을 때까지 반복한다.

방문 처리란, 스택에 한 번이라도 삽입된 노드를 다시 삽입하지 않도록 체크하는 것을 의미한다.
즉, 방문 처리를 함으로써 각 노드를 한 번씩만 처리할 수 있게 한다.

BFS 알고리즘은 큐 자료구조에 기초하기 때문에 deque 라이브러리를 활용하여 구현하며 시간 복잡도는 O(N) 의 시간이 소요된다. 참고로 일반적인 경우에 실제 수행 시간은 DFS 보다 BFS가 좋은 편이다.

BFS 구현 (python)

# deque 라이브러리 불러오기
from collections import deque

# BFS 메서드 정의
def bfs (graph, node, visited):
    # 큐 구현을 위한 deque 라이브러리 활용
    queue = deque([node])
    # 현재 노드를 방문 처리
    visited[node] = True
    
    # 큐가 완전히 빌 때까지 반복
    while queue:
        # 큐에 삽입된 순서대로 노드 하나 꺼내기
        v = queue.popleft()
        # 탐색 순서 출력
        print(v, end = ' ')
        # 현재 처리 중인 노드에서 방문하지 않은 인접 노드를 모두 큐에 삽입
        for i in graph[v]:
            if not (visited[i]):
                queue.append(i)
                visited[i] = True
                
graph = [
    [],
    [2, 3],
    [1, 8],
    [1, 4, 5],
    [3, 5],
    [3, 4],
    [7, 8],
    [6, 8],
    [2, 6, 7]
]

# 노드별로 방문 정보를 리스트로 표현
visited = [False] * 9

# 정의한 BFS 메서드 호출(노드 1을 탐색 시작 노드로 설정)
bfs(graph, 1, visited)

실행 결과
1 2 3 8 4 5 6 7

한 주 회고

나는 나름 자기 객관화에 뛰어나다고 생각해왔다. 그런데, 알고리즘 공부와 CS 공부만큼은 어디서부터 어떻게 정리해가야 할지 감이 계속 잡히질 않는다. 나 자신을 완전히 바닥부터 놓고 시작하면.... 가능하지 않을까?
항해에는 설 연휴가 없지만, 어쨌든 챙겨야 할 가정이 있는 사람으로서 쉬는 시간들에 마음의 쉼을 가지면서.
나의 상태에서 내가 해야 할 것들에 대해 바닥부터 쌓아나가고 싶다.

다음주 (도)

알고리즘 !

profile
KingdomOfGod newPerson = new KingdomOfGod();

0개의 댓글