Leet Code 104. Maximum Depth of Binary Tree

정우성·2022년 1월 14일
0

최근 풀었던 문제들 중 처음 접했을 때 잘 못풀었어서 Tree를 순회하는 방법을 공부하고 다시 풀어보았다.

문제를 처음 접하고 든 생각은 최대깊이를 구해야 하기 때문에 모든 node를 순회하는 방법을 사용해야 한다고 생각했다. 그래서 DFS와 BFS 중 하나를 선택해야 한다고 생각했고 깊이니까 DFS를 사용해야겠다고 근거 없이 결정하고 문제를 접근했다. DFS는 스택을 써야 한다 정도의 개념만 가지고 풀었어서 어떻게 구현할 수 있을까 고민을 하다가 아래 코드를 작성했다.

def maxDepth(self, root: Optional[TreeNode]) -> int:
    if root == None:
        return 0
    pointer = root
    result = 1
    stack = []
    already = []
    while True:
        stack.append(pointer)
        #현재 pointer가 가리키는 node를 stack에 추가
        result = max(result, len(stack))
        #stack의 최대 길이를 result에 지속적으로 저장
        if pointer.left != None and pointer.left not in already:
            pointer = pointer.left
            #위 조건을 만족할 경우 pointer이 left leaf node로 이동
        elif pointer.right != None and pointer.right not in already:
            pointer = pointer.right
            #위 조건을 만족할 경우 pointer이 right leaf node로 이동
        else:
            if pointer == root:
                break
            	#종료조건: root에서 더이상 갈 수 없을 때 loop 종료
            stack = []
            already.append(pointer)
            pointer = root
            #최하위의 leaf node일 때 already에 그 node를 기록
            #stack 초기화 및 pointer 초기화

    return result

테스트 케이스를 통과해 제출을 눌렀으나 Time Limit Exceeded가 떴다. 내가 생각하는 이 에러가 뜬 가장 큰 이유는 root에서 모든 node까지 가는 길을 전부 센 것이 문제라고 생각한다. 최하위의 node를 찍었으면 그 과정에 있던 경로는 굳이 가지 않고 넘겼어야 했다. 두 번째 이유는 Tree 공부를 안한 나

이후 DFS, BFS를 자세히 알아보고 나서는 생각이 바뀌었다. DFS로 구현해도 모든 node를 순회할 수 있지만 depth를 계산하기에는 BFS가 더 간편하다는 결론을 내려 BFS를 사용해 구현하였다.

def maxDepth(self, root: Optional[TreeNode]) -> int:
    if root == None:
        return 0
    queue = [root]
    depth = 0
    while queue:
        depth += 1
        #한 층이 늘어날 때 마다 depth 추가
        for i in range(len(queue)):
            node = queue.pop(0)
            if node.left != None:
                queue.append(node.left)
            if node.right != None:
                queue.append(node.right)
            #한 층의 모든 node를 조회해 그 node의 leaf node들을 queue에 추가
        #for loop가 끝나면 queue에는 다음 층의 모든 leaf node들이 들어감
    return depth

보기에도 더 편하고 직관적인 코드로 변했다. 이렇게 작성한 결과 Success를 받아냈다.

그러나 그다지 빠른 방법이 아니었기 때문에 추가적으로 최적화를 시킬 수 있을 것이다. 최적화 방법으로는 list.pop(0)이 O(N)이기 때문에 O(1)을 할 수 있는 deque를 import해서 사용하는 방법이다. 실제로 28ms가 걸린 경우의 코드는 다음과 같았다. (상위 5% 미만)

문제를 쩔쩔매고 푸는데 Easy라는 난이도가 계속 눈 앞을 어른거렸다. 내가 아직 많이 부족하다는 생각이 들었다. 공부 열심히 하자.

0개의 댓글