땅지원
땅지원's Personal blog
땅지원
전체 방문자
오늘
어제
  • 전체 (353)
    • Frontend (2)
      • React (2)
    • Backend (90)
      • Java (16)
      • Python (19)
      • Spring (23)
      • Database (21)
      • Troubleshooting (8)
    • DevOps (27)
      • ELK (13)
    • CS (40)
    • OS (2)
      • Linux (2)
    • Algorithm (95)
      • concept (18)
      • Algorithm Problem (77)
    • 인공지능 (25)
      • 인공지능 (12)
      • 연구노트 (13)
    • 수업정리 (35)
      • 임베디드 시스템 (10)
      • 데이터통신 (17)
      • Linux (8)
    • 한국정보통신학회 (5)
      • 학술대회 (4)
      • 논문지 (1)
    • 수상기록 (8)
      • 수상기록 (6)
      • 특허 (2)
    • 삼성 청년 SW 아카데미 (6)
    • 42seoul (12)
    • Toy project (3)
    • 땅's 낙서장 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 20.11.6 BB21플러스 온라인 학술대회
  • 20.10.30 한국정보통신학회 온라인 학술대회

인기 글

태그

  • I
  • 이것이 리눅스다 with Rocky Linux9
  • D
  • ㅗ
  • E

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땅지원

땅지원's Personal blog

Coding Test(Union-Find, Disjoint-set)
Algorithm/concept

Coding Test(Union-Find, Disjoint-set)

2022. 5. 22. 15:27

유니온 파인드(Union-Find)

Disjoint-set(서로소 집합, 분리 집합) 이라고도 하며 순수히 노드 간의 연결 관계를 파악할 때 유용하게 사용

무방향 그래프 내에서의 사이클을 판별할 때 사용(서로의 Root Node가 같다면 사이클 발생)

방향 그래프에서 사이클을 판별할 땐 DFS(DFS타다가 자기자신으로 돌아오면 사이클 발생)

0) Make

- 간선이 아직 연결되어있지 않은 그래프에서 모든 값이 자기 자신을 가르키게한다

= > 자기 자신이 부모노드가된다

for(int i=1;i<=N;i++)
    group[i]=i;//자기 자신 넣기

1) Union (서로 다른 노드(집합, 연결관계)를 합쳐서 서로 연결되게 하는 연산)

def union(a, b):
    a = find(a)
    b = find(b)

    # 작은 루트 노드를 기준으로 합침
    if a < b:
        parent[b] = a
    else:
        parent[a] = b
public static void union(int a, int b) {
    int rootA = find(a);
    int rootB = find(b);
    if(rootA < rootB)	//오름차순 
        group[rootB] = rootA;
    else
        group[rootA] = rootB;
}

- 합칠 노드의 루트를 찾은다음 부모노드가 더 작은 애한테 나의 부모는 이제 얘다. 라고 명시해주는 것임

2) Find (Root Node를 찾는 연산)

- 부모 노드를 찾는 것이 아닌 루트 노드를 찾는 것

- parent는 루트 노드를 담는 리스트가 아닌 부모 노드를 담는 리스트이지만

 루트 노드의 정보를 담아서 경로 압축 최적화를 하면 효율적으로 동작

def find(target):
    '''
    #시간복잡도 O(V), 모든 노드를 다 확이하게 되어 비효율적임
    # 여기서는 루트 노드 를 찾아서 return만 시켜준건데
    if parent[target] != target:
        return find(parent[target])
    return target
    '''

    if parent[target] != target:
        # 경로 압축 최적화
        parent[target] = find(parent[target])
    return parent[target]
public static int find(int x) {
		if(group[x]==x)
			return x;
		else
			return find(group[x]);
	}
    
public static int find(int x) {
    if(group[x] != x)
        group[x] = find(group[x]);
    return group[x];
}

 

단순 재귀 호출(주석 부분)

* 경로 압축을 해준다고 해서 parent의 값들이 루트를 가르키는건 아님

* find(target)을 해주니까 루트를 가르킴

경로 압축 최적화를 적용

 

<Code>

# find 연산
def find(target):
    if parent[target] != target:
        # 경로 압축 최적화
        parent[target] = find(parent[target])
    return parent[target]
    
# union 연산
def union(a, b):
    a = find(a)
    b = find(b)

    # 작은 루트 노드를 기준으로 합침
    if a < b:
        parent[b] = a
    else:
        parent[a] = b

parent = [0, 1, 2, 3, 4, 5]

print(find(1), find(2), find(3), find(4), find(5))
print(parent)

union(4, 5)
union(3, 4)
union(2, 3)
union(1, 2)

print(find(1), find(2), find(3), find(4), find(5))
print(parent)

 

 

'Algorithm > concept' 카테고리의 다른 글

Coding Test(Two Pointer)  (0) 2022.06.06
Coding Test(Sliding Window)  (0) 2022.06.06
코딩 테스트를 위한 기술 정리  (0) 2022.05.13
Coding Test(Priority Queue, Heap)  (0) 2022.04.30
Python - 깊은 복사(Deep Copy)  (0) 2022.01.03
    'Algorithm/concept' 카테고리의 다른 글
    • Coding Test(Two Pointer)
    • Coding Test(Sliding Window)
    • 코딩 테스트를 위한 기술 정리
    • Coding Test(Priority Queue, Heap)
    땅지원
    땅지원
    신입 개발자의 우당탕탕 기술 블로그

    티스토리툴바