Skip to main content

Command Palette

Search for a command to run...

[LeetCode] 236. Lowest Common Ancestor of a Binary Tree

Updated
3 min read
[LeetCode] 236. Lowest Common Ancestor of a Binary Tree

Link : 236. Lowest Common Ancestor of a Binary Tree

문제 설명

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Example 1:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

Example 2:

Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Example 3:

Input: root = [1,2], p = 1, q = 2
Output: 1

Constraints:

  • The number of nodes in the tree is in the range [2, 10<sup>5</sup>].

  • -10<sup>9</sup> <= Node.val <= 10<sup>9</sup>

  • All Node.val are unique.

  • p != q

  • p and q will exist in the tree.

문제 분석

글의 내용이 많기는 하지만 말하고자 하는 요점은 아래와 같습니다.

“2개의 노드가 만날 수 있는 가장 가까운 상위노드는 어디인가?”

위 그림과 같이 2개의 노드를 타고서 위로 올라갈때 만날 수 있는 가장 가까운 노드를 찾으면 되는 것이죠

해결 방안

그래서 저는 다음과 같이 문제를 해결하려고 했습니다.

  1. p, q node에 대해서 root 에서 부터 path 배열을 각각 구한다

  2. 2개의 path 정보 중에서 곂치는 노드 중 가장 낮은 위치에 있는 노드를 찾는다

path 배열을 구하기 위해서 재귀를 이용해서 문제를 풀었습니다.

해답 코드

class Solution {
    fun lowestCommonAncestor(root: TreeNode?, p: TreeNode?, q: TreeNode?): TreeNode? {
        val pathToP = ArrayList<TreeNode>()
        val pathToQ = ArrayList<TreeNode>()

        findPath(root, p, pathToP)
        findPath(root, q, pathToQ)

        var lca: TreeNode? = null

        var i = 0
        while (i < pathToP.size && i < pathToQ.size && pathToP[i] === pathToQ[i]) {
            lca = pathToP[i]
            i++
        }

        return lca
    }

    private fun findPath(root: TreeNode?, target: TreeNode?, path: ArrayList<TreeNode>): Boolean {
        if (root == null) return false

        path.add(root)

        if (root === target) return true

        if (findPath(root.left, target, path) || findPath(root.right, target, path)) {
            return true
        }

        path.removeAt(path.size - 1)
        return false
    }
}

class TreeNode(var `val`: Int = 0) {
    var left: TreeNode? = null
    var right: TreeNode? = null
}

느낀점

그래프 문제여서 처음부터 막상 겁을 먹었던 것 같습니다. 하지만 문제를 풀때에 큰 틀에서 우선 접근하고 그다음에 구현에 대해서 신경쓰니깐 그다지 어렵지 않았던 것 같습니다. 특히 AI를 사용해서도 문제를 풀어보고 있는데 정답을 바로 달라고 하는 것이 아니라 먼저 큰 틀을 생각해서 가장 이상적인 순서도를 제시하고 문제를 푸니 문제 해결 속도와 디버깅이 빨라서 생산성이 높아진것도 느낄 수 있었습니다.

More from this blog

카프카 입문 시리즈 2편: 토픽, 파티션, 오프셋

이 글은 Apache Kafka 입문 시리즈의 두 번째 글입니다. 1편에서 살펴본 구성 요소들 위에서, 메시지가 실제로 어떤 구조로 저장되고 관리되는지 알아보겠습니다. 1편을 마치며 세 가지 질문을 남겼습니다. 메시지는 브로커 안에서 어떤 구조로 저장될까? 토픽과 파티션은 정확히 무엇이고, 왜 필요할까? 컨슈머의 오프셋은 어떻게 동작할까? 이번 편에서 이 질문들에 하나씩 답하겠습니다. Topic: 메시지의 논리적 분류 토픽(Topic)은...

Mar 19, 202612 min read7

Java GC의 진화 — Serial에서 Generational ZGC까지

Java가 약속한 것 중 하나는 "메모리는 내가 관리할게"였다. C/C++ 개발자들이 malloc과 free로 메모리와 씨름하던 시절, Java는 Garbage Collector(GC)라는 자동 메모리 관리자를 들고 나왔다. 개발자는 객체를 만들기만 하면 되고, 치우는 건 GC가 알아서 한다. 하지만 "알아서"라는 말에는 대가가 있었다. GC가 동작하는 동안 애플리케이션이 멈추는 것이다. 이 멈춤을 Stop-The-World(STW) 일시 정지...

Mar 16, 20269 min read1

Spring의 3대 철학 — DI, AOP, PSA가 만드는 코드의 품격

Spring을 처음 배울 때, 나는 어노테이션 수집가였다. @Autowired를 붙이면 객체가 알아서 들어오고, @Transactional을 붙이면 트랜잭션이 알아서 관리되고, @Cacheable을 붙이면 캐시가 알아서 동작했다. "알아서"라는 말 뒤에 숨은 원리를 몰랐다. 그냥 마법이라고 생각했다. 그러다 문제가 생겼다. @Transactional을 붙였는데 롤백이 안 됐다. 같은 클래스 안에서 메서드를 호출했기 때문이었다. 원인을 찾는 데 ...

Mar 16, 202611 min read9

Spring Boot Docker 이미지, 한 줄 한 줄에 담긴 고민

처음 Spring Boot 애플리케이션을 Docker로 배포했을 때, Dockerfile은 딱 세 줄이었다. FROM openjdk:17 COPY build/libs/app.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"] 동작은 했다. 하지만 이미지 크기는 700MB를 넘겼고, 코드 한 줄 고칠 때마다 전체 JAR를 다시 빌드해야 했다. 프로덕션에 올릴 때는 root 권한으로 실행되고 있었다. "동작...

Mar 16, 202610 min read4

끄적끄적 테크 블로그

32 posts

물류 회사에 다니고 있는 개발자 블로그입니다. 개발을 너무 좋아해서 정신없이 작업하다가 중간에 끄적거리며 내용들을 몇개 적어봅니다 ㅎㅎ

[LeetCode] 236. Lowest Common Ancestor of a Binary Tree