LeetCode - Same Tree

wodnr_P·2023년 10월 15일
0

LeetCode Top Interview 150

목록 보기
31/32
post-thumbnail

⭐️ LeetCode 알고리즘 풀이 (with Python)

# Same Tree

[Quetion]

LeetCode 100. Same Tree

📌 접근법

[문제 이해]

  • 두 Binary Tree pq가 같은지 확인

두 binary tree가 같은 형태, 같은 값을 가지는지 확인하기 위해서는 모든 노드를 순회해야한다고 생각했고, DFS와 BFS 중 BFS의 방법으로 접근했다.

pq를 순회하며 노드의 값을 저장하고, 만약 트리의 형태가 다르면 (ex: p는 왼쪽 q는 오른쪽에 하위 트리가 구성 되어있는 경우) 순회 결과를 다르게 하기 위해 0을 추가로 삽입했다.

💻 구현

class Solution:
    def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
        # p와 q가 모두 None이거나 한쪽만 None일 경우
        if p is None and q is None:
            return True
        if p is None or q is None:
            return False
        
        p_tree,q_tree=[],[]
        self.level_search(p, p_tree)  
        self.level_search(q, q_tree)
        return p_tree == q_tree
    
    # BFS
    def level_search(self, node, l):
        queue = [(node, 0)]
        while queue:
            node, level = queue.pop(0)
            if node is not None:
                l.append(node.val)
                if node.left:
                    queue.append((node.left, level+1))
                if node.right:
                    queue.append((node.right, level+1))
                else:
                    l.append(0)

Runtime: 32ms | Memory: 16.1MB
LeetCode 코드 중 Runtime 90%, Memory 94% 해당하는 결과

📌 로직 핵심

  • pq 트리를 각각 BFS로 순회
  • node.left가 있고, node.right가 있는 조건과 더불어 0값을 추가하여 하위 트리 형태가 다르면 순회 결과를 다르게 하여 T or F 판단

📝 Same Tree 회고

  • 모든 트리를 순회하고 마지막으로 두 리스트를 비교하기에 최악의 경우 O(N) 시간복잡도를 가지고, 방문한 노드의 값을 모두 저장해야하므로 O(N)의 공간복잡도를 가진다.

  • 시간복잡도는 BFS, DFS 모두 모든 노드를 순회하기 때문에 O(N)으로서, 이미 최적화가 되었다고 생각하고 공간복잡도는 p_tree와 q_tree 리스트를 제거하는 방향으로 개선할 수 있을 것 같다.

# 개선 후
class Solution:
    def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
        if p is None and q is None:
            return True
        if p is None or q is None:
            return False
        
        queue = [(p, q)]
        while queue:
            np, nq = queue.pop(0)
            if np is None and nq is None:
                continue
            
            elif np is None or nq is None or np.val != nq.val:
                return False
            
            queue.append((np.left, nq.left))
            queue.append((np.right, nq.right))
        return True

시간복잡도와 공간복잡도는 여전히 O(N)으로 변함이 없지만 두 리스트를 제거함으로써 메모리에 할당되는 것을 줄였다.

코드도 더 간단해졌지만 while문 내부의 조건문이 길어져서 가독성은 떨어질 수 있겠다고 생각했다.

메모리적으로 더 유리할 수 있지만 개인적으로 개선한 코드보다는 함수로 작성한 이전 로직이 보기에도 편하고, 비즈니스 로직이라고 생각했을 때, 유지보수성이 더 높을 것 같다고 판단된다.

profile
발전하는 꿈나무 개발자 / 취준생

0개의 댓글