💻
ComputerScience
  • 목차
  • Operating System
    • 운영체제란
    • 프로세스 vs 스레드
    • 프로세스 주소 공간
    • 인터럽트(Interrupt)
    • 시스템 콜(System Call)
    • PCB와 Context Switching
    • IPC(Inter Process Communication)
    • CPU 스케줄링
    • 데드락(DeadLock)
    • Race Condition
    • 세마포어(Semaphore) & 뮤텍스(Mutex)
    • 페이징 & 세그먼테이션
    • 페이지 교체 알고리즘
    • 메모리(Memory)
    • 파일 시스템
  • Network
    • OSI 7 계층
    • TCP 3 way handshake & 4 way handshake
    • TCP/IP 흐름제어 & 혼잡제어
    • UDP
    • 대칭키 & 공개키
    • HTTP & HTTPS
    • TLS/SSL handshake
    • 로드 밸런싱(Load Balancing)
    • Blocking,Non-blocking & Synchronous,Asynchronous @LifesLike
    • Blocking & Non-Blocking I/O
  • Algorithm
    • 거품 정렬(Bubble Sort)
    • 선택 정렬(Selection Sort)
    • 삽입 정렬(Insertion Sort)
    • 퀵 정렬(Quick Sort) @mimwin
    • 병합 정렬(Merge Sort)
    • 힙 정렬(Heap Sort)
    • 기수 정렬(Radix Sort)
    • 계수 정렬(Count Sort)
    • 이분 탐색(Binary Search)
    • 해시 테이블 구현
    • DFS & BFS @sujin-kk
    • 최장 증가 수열(LIS)
    • 최소 공통 조상(LCA)
    • 동적 계획법(Dynamic Programming)
    • 다익스트라(Dijkstra) 알고리즘
    • 비트마스크(BitMask)
  • Database
    • 키(Key) 정리
    • SQL - JOIN
    • SQL Injection
    • SQL vs NoSQL
    • 정규화(Nomalization)
    • 이상(Anomaly)
    • 인덱스(INDEX)
    • 트랜잭션(Transaction)
    • 트랜잭션 격리 수준(Transaction Isolation Level)
    • 저장 프로시저(Stored PROCEDURE)
    • 레디스(Redis) @sujin-kk
  • Java
    • Java 컴파일 과정
    • Call by Value vs Call by Reference
    • String & StringBuffer & StringBuilder
    • 자바 가상 머신(Java Virtual Machine)
    • Casting(업캐스팅 & 다운캐스팅)
    • 오토 박싱 & 오토언박싱
    • Thread 활용
    • 고유 락(Intrinsic Lock)
    • 문자열 클래스
    • Garbage Collection
    • Promotion & Casting
    • Primitive type & Reference type
    • 직렬화(Serialization)
    • Error & Exception
    • Stream API
    • Record
    • Composition
Powered by GitBook
On this page
  • 찾는 방법
  • 개선된 LCA 알고리즘
  1. Algorithm

최소 공통 조상(LCA)

Previous최장 증가 수열(LIS)Next다익스트라(Dijkstra) 알고리즘

Last updated 2 years ago

Lowest Common Ancestor란?

최소 공통 조상 찾는 알고리즘

→ 두 정점이 만나는 최초 부모 정점을 찾는 것

찾는 방법

어떻게 찾죠?

해당 정점의 depth와 parent를 저장해두는 방식이다. 현재 그림에서의 depth는 아래와 같을 것이다.

[depth : 정점]
0 → 1(root 정점)
1 → 2, 3
2 → 4, 5, 6, 7

parent는 정점마다 가지는 부모 정점을 저장해둔다. 위의 예시에서 저장된 parent 배열은 아래와 같다.

// 1 ~ 7번 정점 (root는 부모가 없기 때문에 0)
int parent[] = {0, 1, 1, 2, 2, 3, 3}

이제 이 두 배열을 활용해서 두 정점이 주어졌을 때 LCA를 찾을 수 있다. 과정은 아래와 같다.

// 두 정점의 depth 확인하기
while(true){
    if(depth가 일치)
        if(두 정점의 parent 일치?) LCA 찾음(종료)
        else 두 정점을 자신의 parent 정점 값으로 변경
    else // depth 불일치
        더 depth가 깊은 정점을 해당 정점의 parent 정점으로 변경(depth가 감소됨)
}

이런 방식으로 구현할 경우 시간복잡도는 O(depth)가 나온다.

이를 빠르게 하기 위해 이분탐색을 이용해보자.

개선된 LCA 알고리즘

각 노드가 거슬러 올라가는 속도를 2의 제곱 형태로 올라가도록 하여 O(logN)의 시간복잡도를 가집니다.

15칸을 올라가려면 8+4+2+1칸 순서로 올라감

메모리를 더 사용하여 각 노드에 대하여 2^i번째 부모에 대한 정보를 기록합니다.

공간 복잡도를 늘리고 시간 복잡도를 줄이는 Trade-off 기술

img
img