일지/항해99

항해 WEEK2-3 회고록

정요한 2022. 1. 30. 12:44
  • 데이터구조/알고리즘 스터디 시작

새롭게 조를 배정받고 데이터 구조와 알고리즘을 시작했다. 수업 내용이나 가르치시는 방향이 내가 추구하려는 방향과 같았기 때문에 진짜 의지가 없는 나지만 힘내서 강의를 들을 수 있었던것 같다. 또 다행히도 조원분들이 의욕적이시고 어떻게든 하려고 하셔서 같이 자극이 되어서 어찌저찌 강의 내용은 소화를 하고 간것 같다. 과제에 대한 공유도 잘 이루어 져서 좋았다.

 dfs/bfs 때 다같이 어려울때가 진짜 고비여서 1주차 토요일에 못따라겠는 내용들을 반쯤은 놓고 있었는데, 2주차 들어서고 백트래킹, 이진트리 쪽을 공부하는데 쿼리큘럼 자체가 꼬리가 꼬리를 물게 되어 있는것을 확 느끼고, 잘 모르겠다고 미루면 큰일 나겠구나 생각을 해서 다시 돌아가서 진짜 어떻게든 이해하려고 애를 썼던것 같다. 확실히 이렇게 공부를 하니까 진도를 나갈때마다, 어디서 봤던건데? 하는 생각이 들어서 좀 더 쉽게 접근할수 있었던것 같다. 

 알고리즘 인터뷰가 리트코드 기반으로 쓰여진 책인데, 문제에서 주는 input들이 너무 문제를 쉽게 풀게끔 도와주는거 같아서 사실 리트코드에서 직접 제출은 거의 안했고, 파이참으로 직접 input까지 구현하고 문제를 풀었다. 구조를 제대로 구현 할줄도 모르는 수준인데, 구현된 문제 안에서 내용을 조작한다는것이 말이 안된다고 생각했기 때문이다. 확실히 이런것들이 도움이 될것 같은 경험을 몇 번 했다.

 예를 들자면 이진트리의 직렬화/역직렬화 문제를 보고 이게 무슨 말인지도 몰랐는데, 그 전 문제에서 트리의 병합을 할때 leetcode의 input이 문제의 example에서는 list형태이지만, 실제 문제풀이 공간에서 input을 print로 찍어보면 이미 트리 형태로 들어와 있었다. 이런것이 마음에 안들어서 파이참에서 처음부터 리스트 받아서 트리로 만들고, 그 후에 트리내부에서 조작을 하고, 그것을 출력해주기 위해 다시 트리를 리스트로 만들어서 확인을 했었는데 이 과정이 이진트리의 직렬화/역직렬화였다. 백준이나 프로그래머스는 input이 딱 그 input으로 들어가서 input 데이터를 어떻게 조작해야 할지에 대한 고민이 되는데 과정에서 메인으로 진행하는 leetcode의 경우 문제풀이를 위한 문제라는 느낌이 강해서, 그런 것을 넘어 갈 수 있을 정도로 이해가 되지 않았다면 거의 이런식으로 풀었던것 같다. 

# leetcode 617. 14-46 두 이진 트리의 병합
# 두 개의 이진 트리 root1과 root2가 제공됩니다.

# 그들 중 하나를 다른 하나를 덮기 위해 배치할 때 두 트리의 일부 노드는 겹치고 다른 노드는 겹치지 않는다고 상상해 보세요.
# 두 트리를 새로운 이진 트리로 병합해야 합니다. 병합 규칙은 두 노드가 겹치면 노드 값을 합산하여 병합된 노드의 새 값으로 합산하는 것입니다.
# 그렇지 않으면 NOT null 노드가 새 트리의 노드로 사용됩니다.
# 병합된 트리를 반환합니다.
# 참고: 병합 프로세스는 두 트리의 루트 노드에서 시작해야 합니다.

# 로직1) 재귀함수 (노드 val을 받는다. 양 노드를 더한다.)
#       왼쪽으로 가면서 재귀함수, 오른쪽으로 가면서 재귀함수
# 로직2) if node.val==0 이라면 ?

from collections import deque


class TreeNode:  # clear

    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


tr_lst1 = [1, 3, 2, 5, None, None, None]
tr_lst2 = [2, 1, 3, None, 4, None, 7]


def maketree(lst, idx):  # clear
    parent = None
    if idx < len(lst):
        value = lst[idx]
        if value == None:
            return
        parent = TreeNode(value)
        parent.left = maketree(lst, 2 * idx + 1)
        parent.right = maketree(lst, 2 * idx + 2)
    return parent


def mergetree(tr_lst1, tr_lst2):
    print(maketree(tr_lst1, 0).val)  # maketree 검증
    t1 = maketree(tr_lst1, 0)  # list를 tree로 바꿔줌
    t2 = maketree(tr_lst2, 0)  #

    def recur(t1, t2):  # tree 1과 2를 입력해서 시작
        if t1 and t2:  # 둘 다 value가 None이 아니라면
            node = TreeNode(t1.val + t2.val)
            node.left = recur(t1.left, t2.left)
            node.right = recur(t1.right, t2.right)
            return node
        else:
            return t1 or t2

    root = recur(t1, t2)
    # return node

    if len(tr_lst1) >= len(tr_lst2):
        length = len(tr_lst1)
    else:
        length = len(tr_lst2)  # clear

    ## tree형태의 node를 반환하고 다시 list 형태로 바꿔준다.
    return make_lst_by_bst(root, length - 1)


def make_lst_by_bst(root, limit):
    if not root:
        return []

    lst = []
    q = deque([root])

    while q:
        if len(lst) > limit:
            break

        node = q.popleft()
        if node:
            lst.append(node.val)
            q.append(node.left)
            q.append(node.right)
        else:
            lst.append(None)

    print("tree > list", lst)

    return lst


mergetree(tr_lst1, tr_lst2)
  • 데이터구조/알고리즘 조 편성 변경

 2주차가 마무리 되고, 3주차가 시작된지 3일차에 회고록을 쓰고 있는데 이번 조원들이랑은 공부하는 방법이 너무 달라서 조율을 어떻게 해야할지가 고민이다. 게으른 생활을 청산하고 정말 항해가 인생의 분기점이 되었으면 하는 생각으로 결단을 했기 때문에, 여러 가지를 종합해서 중심을 잡고, 내가 정한것을 하는 방향으로 가고 싶었는데, 달라도 너무 다르다.

 내 주장은 이렇다. 지금은 수험생으로 치면 고1 이라고 보기 때문에, 단순히 문제를 많이 봐서 유형에 익숙해지기 보단, 내실을 다져서 나중에 문제를 볼때 문제 풀이 방법만 익히면 빠르게 넘어갈수있는데, 지금부터 구조에 대한 이해없이 무지성으로 문제풀이만 많이 해버리면 진짜 숫자 하나만 바뀌고 문제에서 요구하는 개념 하나만 추가되어도 절대 못풀기 때문이다.

 문제 답 문제 답 이런식으로 공부할거면 수준이 엄청 높아서 당장 다음주에 코테 볼 사람들끼리 해야된다. 근데 그럴 수준이면 항해 올 이유가..? 차라리 sw마에스트로나 saffy전공자반, 우아한 테크코스 등 이런곳을 지원해서 거기서 포트폴리오를 만드는게 훨씬 빠르고 퀄리티도 좋을텐데 하는 생각인데... 결국 알고리즘을 고민하는 과정에서 추후에 실무로 들어갔을때도 분명 문제 해결 능력에서 도움이 될것이라 생각해서 고민없이 문제답 할 생각이 전혀 없기 때문에 조원들과 맞추는게 어려운것 같다. 쉽게 얻은 것은 진짜 운좋거나 천재가 아닌이상 쉽게 사라진다. 난 전혀 천재도 아니고 오히려 머리가 나쁜쪽에 속한다.

 

 깃허브에 매일 푼 문제들에 대해 아카이빙도 할겸 주석을 달아서 올리고는 있는데, 사실상 근본적으로 별 의미는 없고, 그냥 나는 오늘 공부했다를 체크하는 정도로 쓰고 있다. 그러던 중에, 공부한것에 대한 나의 생각을 정리하고 가야겠다라는 생각이 들어서, 알고리즘 문제나 cs의 경우, 좀 오래 고민하거나 왜 이렇게 했지? 라는 생각이 드는 부분은 티스토리에 정리해서 쓰려고 한다. 

https://john3210of.tistory.com/30?category=984891 

 

[python] 연결 리스트, 삽입 정렬 Leetcode 147

파이썬 알고리즘 인터뷰 60번 문제입니다. 처음 접근할때 연결리스트가 미리 쓸수 있게 되어있지 않아서 설마 내가 연결리스트도 구현해줘야하나? 하는 뭔가 이상함을 느끼고 input을 print로 찍어

john3210of.tistory.com

뭔가 좀 부족한 느낌이 많이 들지만 쓰다보면 늘지 않을까 하는 희망을 가지고 이어나가려고 한다.

 

  • 느낀점

    벌써 항해 시작한지 1달이 다 되어간다. 뭔가 얻은게 있냐고 물어보면 그렇다고 할것같다. 나는 가치판단할 수준이 전혀 되지는 않지만, 나에게 가장 부족한 소통하는 이런 것들과, 지식적으로도 원하는 만큼 공부 할 수 있는 환경에 처하게 된것만으로도 아직까진 성공적이라고 생각한다.