RIEN😚
이상한 나라의 개발자
RIEN😚
전체 방문자
오늘
어제
  • 분류 전체보기 (125)
    • Algorithm (68)
      • 알고리즘 (0)
      • Baekjoon (8)
      • 프로그래머스 (55)
      • HackerRank (5)
    • Android (30)
      • Project (1)
      • Error (2)
      • Studio (1)
      • Android (26)
    • Kotlin (6)
    • CS (4)
      • 네트워크 (2)
      • 데이터베이스 (2)
    • Front End (5)
      • React (1)
      • VUE (3)
      • Project (0)
      • 기타 (1)
    • 기록 (11)
      • 회고록 (6)
      • TIL (5)

블로그 메뉴

  • Github🔥
  • 포트폴리오🌹

공지사항

인기 글

티스토리

250x250
반응형
hELLO · Designed By 정상우.
RIEN😚
Algorithm/프로그래머스

[Lv3] 섬 연결하기 - python, kotlin

Algorithm/프로그래머스

[Lv3] 섬 연결하기 - python, kotlin

2022. 9. 29. 09:41
728x90
반응형
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 설명

n 개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution 을 환성하세요.

다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다.

예를 들어 A 섬과 B 섬 사이에 다리가 있고, B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.

 

제한 사항

1. 섬의 개수 n은 1 이상 100 이하입니다.

2. costs의 길이는 ((n-1)*n)/2이하입니다.

3. cost = [i, j, c] = i 섬과 j 섬을 연결하는 다리를 건설할 때 드는 비용 c

4. 같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다.

5. 모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.

6. 연결할 수 없는 섬은 주어지지 않습니다.

 

풀이

문제를 읽어보면 어떠한 알고리즘을 사용할 수 있는지 알 수 있어요.

🌹 최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소비용

바로! 크루스칼 알고리즘입니다! 😆

크루스칼 알고리즘은 Union&Find 알고리즘을 사용해서 최소 신장 트리를 만들어, 모든 정점을 연결하는데 필요한 최소 비용을 구할 때 사용할 수 있어요.

 

그럼 코드를 하나씩 생각해보면서 문제를 풀어보겠습니다. 🤗

1. costs 비용 정렬하기

먼저 가중치(cost)가 가장 적은 간선부터 순차적으로 탐색할 수 있도록 주어진 costs를 '다리를 건설할 때 드는 비용'에 따라 정렬하도록 하겠습니다.

python
costs.sort(key = lambda x : x[2])
kotlin
costs.sortBy { it[2] }

2. Union & Find

Union & Find 알고리즘에 필요한 코드는 3가지가 있어요,

  • 특정 정점의 parent를 찾는 메서드 -> getParent(x)
  • 두 그룹을 하나로 합치는 메서드 -> union(x, y)
  • 두 정점이 같은 그룹에 포함되었는지 확인하는 메서드 -> find(x, y)
getParent(x)
def getParent(x):
	if parent[x] = x : return x
    parent[x] = getParent(parent[x])
    return parent[x]
private fun getParent(x: Int): Int =
	if (parent[x] == x) x
    else {
    	parent[x] = getParent(parent[x])
        parent[x]
    }
union(x, y)
def union(x, y):
	a = getParent(x)
    b = getParent(y)
    if a < b : parent[b] = a
    else: parent[a] = b
private fun union(x: Int, y: Int) {
	val a = getParent(x)
    val b = getParent(y)
    if (a < b) parent[a] = b else parent[b] = a
}
find(x, y)
def find(x, y):
	a = getParent(x)
    b = getParent(y)
    if a == b : return True
    return False
fun find(x: Int, y: Int): Boolean {
    val a = getParent(x)
    val b = getParent(y)
    return a == b
}

그러면 정렬된 costs와 Union & Find 메서드들을 사용한 크루스칼 알고리즘을 구현해보겠습니다.

 

코드

python
parent = []
def solution(n, costs):
    global parent
    answer = 0
    # Union & Find
    parent = [x for x in range(n)]
    # 가중치의 오름차순으로 정렬
    costs.sort(key = lambda x : x[2])
    
    for s, e, c in costs:
        if find(s,e): continue
        answer += c
        union(s,e)
    
    return answer

def getParent(x):
    global parent
    if parent[x] == x: return x
    parent[x] = getParent(parent[x])
    return parent[x]

def union(x, y):
    global parent
    a = getParent(x)
    b = getParent(y)
    if a < b: parent[b] = a
    else: parent[a] = b
    
def find(x, y):
    a = getParent(x)
    b = getParent(y)
    if a == b: return True
    return False
kotlin
class Solution {
    
    lateinit var parent: IntArray
    fun solution(n: Int, costs: Array<IntArray>): Int {
        var answer = 0

        parent = IntArray(n){ it }
        costs.sortBy { it[2] }

        costs.forEach { (s, e, cost) ->
            if (find(s, e).not()) {
                answer += cost
                union(s, e)
            }
        }

        return answer
    }

    private fun getParent(x: Int): Int =
        if (parent[x] == x) x
        else {
            parent[x] = getParent(parent[x])
            parent[x]
        }
    
    fun union(x: Int, y: Int) {
        val a = getParent(x)
        val b = getParent(y)
        if (a < b) parent[a] = b else parent[b] = a
    }
    
    fun find(x: Int, y: Int): Boolean {
        val a = getParent(x)
        val b = getParent(y)
        return a == b
    }
}
반응형

'Algorithm > 프로그래머스' 카테고리의 다른 글

[Lv3] 가장 긴 팰린드롬 - python  (0) 2022.09.29
[Lv3] 단어 변환 - python  (1) 2022.09.29
[프로그래머스] Lv 3. 파괴되지 않은 건물(Kotlin)  (0) 2022.06.06
[프로그래머스] Lv 3. 순위  (0) 2022.06.06
[프로그래머스] Lv 3. 네트워크(Kotlin)  (0) 2022.06.06
  • 문제 설명
  • 제한 사항
  • 풀이
  • 코드
'Algorithm/프로그래머스' 카테고리의 다른 글
  • [Lv3] 가장 긴 팰린드롬 - python
  • [Lv3] 단어 변환 - python
  • [프로그래머스] Lv 3. 파괴되지 않은 건물(Kotlin)
  • [프로그래머스] Lv 3. 순위
RIEN😚
RIEN😚
안드로이드 / 코틀린 독학으로 취업하자!

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.