>

TIL

4주차 Day 4. 연결 리스트, 트리

ekdud 2024. 7. 18. 09:35

🤍

     

    연결리스트와 배열의 차이

     

    리스트(list)는 선형적으로(순서가 존재한다는 뜻) 값들을 가지고 있는 자료구조로, 배열(array)과 연결리스트(linked list)로 나누어진다.

     

      배열은 파이썬의 리스트로, 접근이 쉽고 삽입, 삭제가 어렵다. 접근에 O(1), 삽입/삭제에 O(n)이 걸림. 연결리스트는 직접 구현해야하며 접근이 어렵고 삽입, 삭제가 쉽다. 접근에 O(n), 삽입/삭제에 O(1) 소요.

    연결 리스트는 비록 랜덤 엑세스불가하지만 삽입/삭제 연산의 용이함은 스택, 큐, 덱 등의 기본적인 자료구조를 구현하는 데 많은 도움이 된다.

    * 랜덤 액세스: 특정 인덱스의 값을 O(1)만에 참조하는 것. 연결리스트는 k번째 값에 접근하는 데 O(k)만큼 걸림.

     

     

    연결리스트 구현

    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    
    
    class LinkedList:
        def __init__(self):
            self.head = None
    
        def append(self, val):
            if not self.head:
                self.head = ListNode(val, None)
                return
    
            node = self.head
            while node.next:
                node = node.next
    
            node.next = ListNode(val, None)

     

     

     

    그래

    - 연결되어 있는 정점과 정점간의 관계를 표현할 수 있는 자료구조.

    - 자료구조는 크게 비선형구조, 선형구조(ex. 배열, 리스트, 스택, 큐)로 구분되는데, 트리와 그래프가 대표적인 비선형 자료구조이며, 그래프는 연결 관계에 초점이 맞춰져 있다. 

    - 유방향 그래프(Directed Graph)와 무방향 그래프(Undirected Graph)가 있다. 

    - 유방향 그래프는 단방향 관계를 나타내는, 방향을 가지는 간선을 갖는다.

    - 무방향 그래프는 방향이 없는 간선을 갖는다.

     

     

    그래프의 표현방법

    1. 인접 행렬(Adjacency Matrix): 2차원 배열로 그래프의 연결 관계를 표현.

    2. 인접 리스트(Adjacenct List): 연결 리스트로 그래프의 연결 관계를 표현.

    https://laboputer.github.io/ps/2017/09/29/graph/

     

    - 공간복잡도 측면에서 인접 리스트가 유리하기 때문에 일반적으로는 인접 리스트를 많이 쓴다. 하지만 인접 행렬은 랜덤 액세스가 가능하다는 장점이 있어 그때그때 적절한 것을 사용하면 된다.

     

     


     

    ALGORITHM CODE KATA

     

    Ⅰ. 숫자나라 기사단의 각 기사에게는 1번부터 number까지 번호가 지정되어 있습니다. 기사들은 무기점에서 무기를 구매하려고 합니다. 각 기사는 자신의 기사 번호의 약수 개수에 해당하는 공격력을 가진 무기를 구매하려 합니다. 단, 이웃나라와의 협약에 의해 공격력의 제한수치를 정하고, 제한수치보다 큰 공격력을 가진 무기를 구매해야 하는 기사는 협약기관에서 정한 공격력을 가지는 무기를 구매해야 합니다. 예를 들어, 15번으로 지정된 기사단원은 15의 약수가 1, 3, 5, 15로 4개 이므로, 공격력이 4인 무기를 구매합니다. 만약, 이웃나라와의 협약으로 정해진 공격력의 제한수치가 3이고 제한수치를 초과한 기사가 사용할 무기의 공격력이 2라면, 15번으로 지정된 기사단원은 무기점에서 공격력이 2인 무기를 구매합니다. 무기를 만들 때, 무기의 공격력 1당 1kg의 철이 필요합니다. 그래서 무기점에서 무기를 모두 만들기 위해 필요한 철의 무게를 미리 계산하려 합니다. 기사단원의 수를 나타내는 정수 number와 이웃나라와 협약으로 정해진 공격력의 제한수치를 나타내는 정수 limit와 제한수치를 초과한 기사가 사용할 무기의 공격력을 나타내는 정수 power가 주어졌을 때, 무기점의 주인이 무기를 모두 만들기 위해 필요한 철의 무게를 return 하는 solution 함수를 완성하시오.

    (school.programmers.co.kr)

    def solution(number, limit, power):
        knight = [i for i in range(1, number+1)]
        div = [0]*number # 공격력 = 약수의 개수
        
        for i in range(len(knight)): # 1 ~ number 순회
            for j in range(1, int(knight[i]**0.5) + 1): # 1 ~ 기사번호의 제곱근
                if knight[i]%j == 0:
                    div[i] += 1
                    if j**2 != knight[i]:
                        div[i] += 1     
                        
        for i in range(len(div)):
            if div[i] > limit:
                div[i] = power
                
        iron = sum(div)     
        return iron

     

    저 코드만 두시간을 붙잡고 있었는데... ㅋㅋㅋ 정말 어이없는 실수였다.  for j in range(1, int(knight[i]**1/2) + 1):  이라고 작성했더니 계속 정답이 안나와서 1/2 대신 0.5로 썼더니 정답이 나오는 게 아닌가? 알고보니까 연산이 앞에서부터 되니까 (1/2)처럼 괄호 안에 넣어주지 않으면 knight[i]**1을 먼저하고 2로 나누는 것이어서 계속 오답이 나왔던 것. ㅠㅠ 괄호 주의하자.  for j in range(1, int(knight[i]**(1/2)) + 1):   또는   for j in range(1, int(knight[i]**0.5) + 1):  로 써야했다.