본문 바로가기
TechStudy/CodingTest

chp9 트리(tree)

이 글은 골든래빗 <코딩 테스트 합격자되기 파이썬편>의 9장 써머리입니다.

 

[트리 기본 개념]: 계층 구조(파일 시스템, 디렉토리 같은 것)

활용 예): 인공지능(결정트리), 자동 완성 기능(trie: 자동 검색어 추천 기능), 데이터베이스(B-트리, B+트리로 인덱싱)

트리 구조. 여기서 전체 높이는 3이다.

node(노드): 트리를 구성하는 각각의 종착점(동그라미)

root node(루트 노드): 노드 중 가장 위에 있는 노드

edge(간선= 에지): the line connecting nodes

level(레벨): root node ~ 해당 node까지 필요한 edge(간선) 수의 최솟값

degree(차수): 특정 노드에서 아래로 향하는 edge(간선) 개수

 

parent node(부모 노드): 상대적으로 위에 있으면 부모 노드

child node(자식 노드): 상대적으로 밑에 있으면 자식 노드

siblings(형제 노드): 같은 부모 노드를 가진 서로 다른 노드

leaf node(리프 노드): 자식이 없는 노드(말단 노드)

 

 

 

 

 

코딩 테스트에서는 binary tree(이진 트리)만 제대로 알면 된다. (edge가 최대 2개인 트리)

이진 트리 표현 방법은 1)배열, 2)포인터 가 있다.

 

1-1) 배열
배열로 표현시 다음과 같은 규칙을 전제한다.

 

  • 루트 노드 = 인덱스 1
  • 왼쪽 자식 노드 = 부모 노드 인덱스 * 2
  • 오른쪽 자식 노드 = 부모 노드 인덱스 * 2 + 1

 

여기서 0인 경우

 

  • 루트 노드 = 인덱스 1
  • 왼쪽 자식 노드 = 부모 노드 인덱스 * 2 + 1
  • 오른쪽 자식 노드 = 부모 노드 인덱스 * 2 + 2

로 규칙을 만들 수 있다. 그러나 1부터 시작하는 것이 여러모로 효율적이다.

배열로 표현한 이진 트리.&nbsp; 편의를 위해 인덱스 0은 사용하지 않는다.

즉, 왼쪽은 단순 2배. 오른쪽은 (2배 + 1)   인덱스이다.

 

이 방법은 보통 노드가 N개일 때 시간복잡도는 O(N)이다. 

메모리 낭비 우려가 있더라도 공간복잡도가 허용된다면 구현 난이도가 쉬운 이 방법을 쓰는 것이 좋다.

대부분 코딩 테스트는 이 방법을 써도 문제가 없는 경우가 많다.

 

 

 

 

1-2) 배열 순회 (전위 순회 = preorder): 현재 노드 = 부모 노드일 때, 부모 -> 왼쪽 자식 -> 오른쪽 자식 순서 방문

순회: 데이터를 빠짐없이 방문하는 것

 

전위 순회는 가장 직관적인 방법이다.(거치는 노드를 방문처리하기 때문)

그림 상으로 왼쪽이 전부 방문되면 오른쪽 하나씩 방문이 되는 양상이다.

 

위 사진을 기준으로 한다면

A(현재 루트 노드) -> B(왼쪽 자식 ~> 현재 부모노드) -> D(왼=현 부모) -> H(리프. 이제 올라감) -> I(오른쪽 자식)

-> E(오른쪽 자식 = 현재 부모노드) -> J(리프. 이제 올라감) -> K(오른쪽 자식) -> C(오른쪽 자식) -> F -> G

 

 

 

 

1-2) 배열 순회 (중위 순회 = inorder): 현재 노드 = 부모 노드일 때, 왼쪽 -> 부모 -> 오른쪽 방문

초심자에게 난해하다고 여겨질 수 있는 순회 방법이다.

 

위 사진을 기준으로 한다면

A(현재 루트 노드 = 부모노드)에서 우선순위가 왼쪽이므로 왼쪽인 B로 이동한다. (방문 X)
-> B도 같은 이유로 D로 이동한다. (방문 X)
-> D에서 왼쪽 리프 식인 H를 방문한다. 

-> H 방문 후 그다음 순서인 부모 노드 D를 방문한다 (H -> D)

-> 여기서 오른쪽 노드 I를 방문한다(여기서 오른쪽 노드가 없다면 또 우선순위인 부모 노드 B를 방문한다.)

-> (H -> D -> I ) -> B를 방문한다. 여기서 왼-부-오 순서에 따라 E를 방문하고 J 와 K를 방문한다.

순서는 H -> D -> I -> B -> E -> J -> K -> A -> C -> F -> G

여기서 G에 왼쪽 자식노드가 있는 경우, G의 왼쪽 자식노드를 먼저 방문하고 G를 방문한다.

즉,  H -> D -> I -> B -> E -> J -> K -> A -> C -> F -> (G의 왼쪽 자식 노드) -> G

 

철저하게 왼-부-오 과정을 우선순위로 방문하는 순회함을 유의한다.

 

 

 

 

1-2) 배열 순회 (후위 순회 = postorder): 현재 노드 = 부모 노드일 때, 왼쪽 -> 오른쪽 -> 부모

노드 삭제가 필요할 때 자식노드부터 차근차근 없애는 개념으로 자주 활용된다.

 

위 사진을 기준으로 한다면

A도 왼쪽이 아니므로 B로 이동 -> B도 왼쪽이 아니므로 D로 이동 -> H 방문 -> I 방문 -> D 방문

(H -> I -> D)에서 E를 갔는데 왼쪽이 있으므로 J -> K -> E로 방문

결론: H -> I -> D -> J -> K -> E -> B -> F -> G -> C -> A

 

 

 

2) 포인터

포인터 표현 방법은 (왼쪽 자식 객체 주소, 부모 노드 값, 오른쪽 자식 객체 주소) 이런식으로 부모 노드를 기준으로 양쪽의 객체 주소를 연결하는 방식이다. 메모리 공간을 낭비하지 않는다는 장점은 있지만 구현 난이도는 상대적으로 높다.

 

 

 

 

 

[트리 실전 문법]: 트리 효율적 수축 -> 탐색 효율 증가

이진탐색트리: 부모노드보다 데이터 크기 작으면 왼쪽에, 같거나 크면 오른쪽에 배치하는 정렬방식 사용

탐색 방법:

if target == current node: -> 탐색 종료 

if target < current node: -> left node 탐색

if target > current node: -> right node 탐색

else: 이 트리엔 target 값 없음

 

보통 배열 탐색 O(N)에 비해서 이진탐색은 O(logN)이다.

이진탐색이 오른쪽 노드에만 치우져서 배열탐색과 유사해진 O(N)의 경우를 제외하면

보통은 이진탐색이 성능이 좋다고 판단할 수 있다.

 

이 예외사항을 보완하기위한 balanced binary search tree(균형 이진 탐색 트리) 개념도 있다.

여기선 또 AVL트리, 레드 - 블랙 트리 등으로 나눠지고 항상 O(logN)을 유지할 수 있다.

그러나 균형이진탐색트리는 구현난이도가 너무 높아서 코딩테스트에 안나올 가능성이 높다.

 

 

 

 

 


 

문제 26) 트리 순회

 

주어진 트리에 대해 전위, 중위, 후위 순회를 구현하세요.

 

 

 

 

 

해당 문제는 인덱스 0으로 시작하는 경우이다.

우선 저자의 풀이를 하나하나 입력해보면서 구현 방식을 이해해보자.

# 현재=부모노드 일때 전위) 부모 왼 오 // 중위) 왼 부모 오 // 후위) 왼 오 부모

def preorder(nodes, idx):  # 부모 - 왼 - 오 순회하기 (재귀)
    if idx < len(nodes): # idx = 현재 인덱스 위치
        result = str(nodes[idx]) + " "  # 현재 노드값 + 띄어쓰기 공백 저장
        result += preorder(nodes, idx*2 + 1) # 왼쪽 노드 재귀
        result += preorder(nodes, idx*2 + 2) # 오른쪽 노드 재귀
        return result
    else: # 길이 넘어가면 빈 문자열
        return ""

def inorder(nodes, idx): # 왼 - 부모 - 오 순회하기
    if idx < len(nodes):
        result = inorder(nodes, idx * 2 + 1) # 왼쪽 노드 재귀
        result += str(nodes[idx]) + " "  # 부모 노드
        result += inorder(nodes, idx * 2 + 2)  # 오른쪽 노드 재귀
        return result
    else:
        return ""

def postorder(nodes, idx): # 왼 - 오 - 부모
    if idx < len(nodes):
        result = postorder(nodes, idx * 2 + 1) # 왼쪽 노드 재귀
        result += postorder(nodes, idx * 2 + 2) # 오른쪽 노드 재귀
        result += str(nodes[idx]) + " " # 부모 노드
        return result
    else:
        return ""

def solution(nodes):
    return [preorder(nodes, 0)[:-1], inorder(nodes, 0)[:-1], postorder(nodes, 0)[:-1]]



assert solution([1,2,3,4,5,6,7]) == ["1 2 4 5 3 6 7", "4 2 5 1 6 3 7", "4 5 2 6 7 3 1"]

 

 

 

 

 

 

 

인덱스 1부터 시작하는 경우로 바꾸어보자

# 인덱스 1로 시작하는 형태로 변형된 답안이다.
def preorder(nodes, idx):  # 부모 - 왼 - 오 순회하기 (재귀)
    if idx < len(nodes): # idx = 현재 인덱스 위치
        result = str(nodes[idx]) + " "  # 현재 노드값 + 띄어쓰기 공백 저장
        result += preorder(nodes, idx*2) # 왼쪽 노드 재귀
        result += preorder(nodes, idx*2 + 1) # 오른쪽 노드 재귀
        return result
    else: # 길이 넘어가면 빈 문자열
        return ""

def inorder(nodes, idx): # 왼 - 부모 - 오 순회하기
    if idx < len(nodes):
        result = inorder(nodes, idx * 2) # 왼쪽 노드 재귀
        result += str(nodes[idx]) + " "  # 부모 노드
        result += inorder(nodes, idx * 2 + 1)  # 오른쪽 노드 재귀
        return result
    else:
        return ""

def postorder(nodes, idx): # 왼 - 오 - 부모
    if idx < len(nodes):
        result = postorder(nodes, idx * 2) # 왼쪽 노드 재귀
        result += postorder(nodes, idx * 2 + 1) # 오른쪽 노드 재귀
        result += str(nodes[idx]) + " " # 부모 노드
        return result
    else:
        return ""

def solution(nodes):
    nodes = [-1] + nodes # 인덱스 0자리에 아무거나 삽입
    return [preorder(nodes, 1)[:-1], inorder(nodes, 1)[:-1], postorder(nodes, 1)[:-1]]



assert solution([1,2,3,4,5,6,7]) == ["1 2 4 5 3 6 7", "4 2 5 1 6 3 7", "4 5 2 6 7 3 1"]

위에서 정리한 내용대로 재귀에 더해주는 값과 처음 nodes에 대한 변형만 해주면 문제없이 잘 작동된다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

문제 27) 이진 탐색 트리 구현

lst로 이진 탐색 트리를 생성하고 search_lst에 있는 각 노드를 해당 트리에서 찾을 수 있는지 여부를 판별하세요.

 

저자의 답안이다. (클래스 활용한 답안)

# ➊ 노드 클래스 정의
class Node:
    # ➋ 노드 클래스 생성자
    def __init__(self, key):
        self.left = None
        self.right = None
        self.val = key


# ➌ 이진 탐색 트리 클래스
class BST:
    # ➍ 초기에 아무 노드도 없는 상태
    def __init__(self):
        self.root = None

    # ➎ 루트 노드부터 시작해서 이진 탐색 트리 규칙에 맞는 위치에 새 노드 삽입
    def insert(self, key):
        # 루트 노드가 없는 경우 새로운 노드를 루트 노드로 추가
        if not self.root:
            self.root = Node(key)
        else:
            curr = self.root
            while True:
                # 삽입하려는 값이 현재 노드의 값보다 작은 경우 왼쪽 자식 노드로 이동
                if key < curr.val:
                    if curr.left:
                        curr = curr.left
                    else:
                        # 현재 노드의 왼쪽 자식 노드가 없는 경우 새로운 노드 추가
                        curr.left = Node(key)
                        break
                else:
                    # 삽입하려는 값이 현재 노드의 값보다 큰 경우 오른쪽 자식 노드로 이동
                    if curr.right:
                        curr = curr.right
                    else:
                        # 현재 노드의 오른쪽 자식 노드가 없는 경우 새로운 노드 추가
                        curr.right = Node(key)
                        break

    # ➏ 이진 탐색 규칙에 따라 특정값이 있는지 확인(루트 노드부터 시작)
    def search(self, key):
        curr = self.root
        # 현재 노드가 존재하고, 찾으려는 값과 현재 노드의 값이 같지 않은 경우 반복
        while curr and curr.val != key:
            # 찾으려는 값이 현재 노드의 값보다 작은 경우 왼쪽 자식 노드로 이동
            if key < curr.val:
                curr = curr.left
            else:
                # 찾으려는 값이 현재 노드의 값보다 큰 경우 오른쪽 자식 노드로 이동
                curr = curr.right
        return curr


# ➐ lst에 있는 데이터를 활용해서 이진 탐색 트리 생성, search_lst 원소 탐색
def solution(lst, search_lst):
    bst = BST()
    # 리스트의 각 요소를 이용하여 이진 탐색 트리 생성
    for key in lst:
        bst.insert(key)
    result = []
    # 검색 리스트의 각 요소를 이진 탐색 트리에서 검색하고, 검색 결과를 리스트에 추가
    for search_val in search_lst:
        if bst.search(search_val): # 이건 True False 직접 삽입해야 可
            result.append(True)
        else:
            result.append(False)
    return result






assert solution([5,3,8,4,2,1,7,10], [1,2,5,6] ) == [True, True, True, False]
assert solution([1,3,5,7,9], [2,4,6,8,10]) == [False, False, False, False, False]

 

 

 

 

 

 

 

 

 

 

문제 28) 예상 대진표

https://school.programmers.co.kr/learn/courses/30/lessons/12985

 

프로그래머스

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

programmers.co.kr

대진표를 구현해야하는가? -> 구하고자하는 것이 뭐지? -> 구하고자 하는 것만 계산하면 되겠네?

# 번호 갱신: 2로 나눈 값. 홀수번호는 나눈 값 올림처리.
# n = 게임 참가자 수 // a = 참가자 번호 // b = 경쟁자 번호   (무조건 만나기 전까지 이긴다 가정)
# 목적: a는 b를 몇 번째 라운드에서 만나나?

# 만나는 것 의미: a와 b의 번호 숫자 차이 = 1 일 때 만난다.
# 몇 번 나눠져야 둘이 1 차이 나는지 계산
# 반례: a와 b가 1차이가 난다고해도 a가 2, b가 3이면 만난 것이 아님
# a와 b 차이가 0이되는 순간에 -1 한 것이 답
from math import ceil

def solution(n,a,b):
    count = 0
    while abs(a - b) != 0:  # 1로 하면 몇 개가 통과가 안됨(반례때문)
        a, b = ceil(a/2), ceil(b/2)
        count += 1
    return count

 

여기서 n이 쓸모가 없다.

그러나 차이를 1로 잡았다가 반례를 못찾아서 헤맸었다. 사실 0으로 해도 되었던 것이었는데..

 

 

 

저자의 답안

def solution(n, a, b):
  answer = 0
  while a != b:
    a, b = (a + 1) // 2, (b + 1) // 2
    answer += 1
  return answer

굳이 math를 불러오지않고 이렇게 할 수도 있겠다 싶다.

 

 

 

타인의 풀이 (더더욱 숏코딩)

def solution(n,a,b):
    count = 0
    while (a-1) // (2**count) != (b-1) // (2**count):
        count += 1
    return i

이렇게 하면 1줄이 더 줄어든다.

 

 

 

 

이건 뭔데(이진법어쩌구..)

def solution(n,a,b):
    return ((a-1)^(b-1)).bit_length()

XOR연산이 어쩌구 저쩌구..

 

 

 

 

 

 

 

 

 

 

 

 

 

 

문제 29) 다단계 칫솔 판매 (Dev-Matching 웹 백앤드 개발자 2021 상반기)

https://school.programmers.co.kr/learn/courses/30/lessons/77486

 

프로그래머스

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

programmers.co.kr

문제 풀이 스스로 하지못하여서 답지를 참고하였다.

# enroll = 각 판매원 이름 // referral = 각 판매원의 추천인 // seller = 판매자 // amount = 판매량
# 칫솔 1개당 100원 -> amount * 100 = 얻은 수익
# 추천인 없으면 '-'
# 목적: 각 판매원이 받은 이득 리스트 출력
# dt1 = {회원 : 추천인} // dt2 = {회원 : 금액}
# dt2가 정답틀
def solution(enroll, referral, seller, amount):
    dt1 = dict(zip(enroll, referral)) # {회원 : 추천인}
    dt2 = dict(zip(enroll, [0]*len(enroll))) # {회원 : 초기값 0원}

    for i in range(len(seller)):
        money = amount[i] * 100
        current_name = seller[i]
        while money >= 1 and current_name != '-': #돈이 1원 이상이고 '-'가 아닐 때 계속 진행
            dt2[current_name] += money - money // 10
            current_name = dt1[current_name]
            money //= 10

    return [dt2[name] for name in enroll]

for 루프 기준, while 조건 기준, 10으로 나누는 몫 반환 개념으로 자동 반올림(?) 효과를 주는 것이 특징적이다.

 

갱신은 money값, 현재의 name값

 

 

 

 

 

 

 

 

 

 

 

 

문제 30) 미로 탈출 

https://school.programmers.co.kr/learn/courses/30/lessons/159993

 

프로그래머스

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

programmers.co.kr

책의 풀이는 3차원 배열을 쓰는데 나는 그 대신에 내가 생각했던 로직과 유사한 타인의 풀이에 내 방식을 조금 섞었다.

from collections import deque

def bfs(begin, finish, maps):
    visited = [[False] * len(maps[0]) for _ in range(len(maps))] # 방문 통
    dx, dy = [-1, 1, 0, 0], [0, 0, -1, 1] # 좌표
    q = deque() 
    q.append(begin)  # 시작점 대입
    t = 0 # 시간
    while q:
        x, y = q.popleft()
        
        if x == finish[0] and y == finish[1]:
            return t
        
        for i in range(4): # 상하좌우 이동
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < len(maps) and 0 <= ny < len(maps[0]) and not visited[nx][ny] and maps[nx][ny] != 'X':
                t += 1
                visited[nx][ny] = True
                q.append((nx,ny))
                    

def solution(maps):
    for i in range(len(maps)): # 행
        for j in range(len(maps[0])): # 열
            if maps[i][j] == "S": start = (i, j)
            elif maps[i][j] == "L": lever = (i, j)
            elif maps[i][j] == "E": end = (i, j)

    distance1 = bfs(start, lever, maps)
    distance2 = bfs(lever, end, maps)
    
    return distance1 + distance2 if distance1 and distance2 else -1

 

근데 이렇게하면 통과가 안된다. t 계산이if조건문이 있음에도 상하좌우 여러번 계산되기 때문이다.

안전하게 deque에 넣어서 갱신하는것이 적절하다.

 

 

from collections import deque

def bfs(begin, finish, maps):
    visited = [[False] * len(maps[0]) for _ in range(len(maps))]  # 방문 통
    begin.append(0)  # time 초기값 t = 0을 삽입
    q = deque([begin])  # 시작점 대입

    while q:
        x, y, t = q.popleft()

        if x == finish[0] and y == finish[1]:
            return t

        for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:  # 상하좌우 이동
            nx, ny = x + dx, y + dy
            if 0 <= nx < len(maps) and 0 <= ny < len(maps[0]) and not visited[nx][ny] and maps[nx][ny] != 'X':
                visited[nx][ny] = True
                q.append([nx, ny, t+1])  # t 갱신은 q내부에서해야 안전하다.


def solution(maps):
    for i in range(len(maps)):  # 행
        for j in range(len(maps[0])):  # 열
            if maps[i][j] == "S": start = [i, j]
            elif maps[i][j] == "L": lever = [i, j]
            elif maps[i][j] == "E": end = [i, j]

    distance1 = bfs(start, lever, maps)
    distance2 = bfs(lever, end, maps)

    return distance1 + distance2 if distance1 and distance2 else -1

그리고 x y 상하좌우 돌리는 코드도 사실 for문에서 한 줄로 끝낼 수 있다.

기존 위의 것 처럼 dx, dy 따로 정의해서 i로 돌리는 것보다 나은듯.

 

 

 

 

 

 

내가 참고했던 사람이 사용한 방법은 visited을 0으로 두고 1씩 더해가는 방식을 사용했다.

# 목적: 미로탈출 최단시간   조건: 1칸 = 1초 = 거리, 레버 당기고 탈출구 가야함, 불가능 = -1

from collections import deque

def bfs(begin, finish, maps): #(시작점, 끝점, 밑바탕 그래프)
    visited = [[0] * len(maps[0]) for _ in range(len(maps))]  # 방문 통
    q = deque([begin])   # 시작점 대입

    while q:
        x, y = q.popleft()

        if x == finish[0] and y == finish[1]:  # 도착하면 종료
            return visited[finish[0]][finish[1]]  # 거리값 출력

        for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:  # 상하좌우 이동
            nx, ny = x + dx, y + dy
            if 0 <= nx < len(maps) and 0 <= ny < len(maps[0]) and not visited[nx][ny] and maps[nx][ny] != 'X':
                visited[nx][ny] = visited[x][y] + 1
                q.append([nx, ny])

def solution(maps):
    for i in range(len(maps)):  # 행
        for j in range(len(maps[0])):  # 열
            if maps[i][j] == "S": start = [i, j]
            elif maps[i][j] == "L": lever = [i, j]
            elif maps[i][j] == "E": end = [i, j]

    distance1 = bfs(start, lever, maps)
    distance2 = bfs(lever, end, maps)

    return distance1 + distance2 if distance1 and distance2 else -1

 

배울점: S, L, E의 좌표를 찾는 아이디어.

             distance를 2번 계산해서 더하는 아이디어.

             visited을 0으로 초기화한 후에 +1을 더하는 방식으로 거리를 자동 계산하는 아이디어

             deque()로 정의하는 줄 없이 바로 append로 시작하는 아이디어

주의점: len(maps)와 len(maps[0])의 행 열 개념이 헷갈릴 수 있다. 반대로 작성했었다.

 

 

 

 

 

 

 

 

 

 

 

 

문제 31) 양과 늑대 (카카오 2022)

https://school.programmers.co.kr/learn/courses/30/lessons/92343

 

프로그래머스

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

programmers.co.kr

저자의 풀이를 보고 공부하자.

# 이진트리, 루트노드는 무조건 양 = 0 // if 양 <= 늑대(1): 양 잡아먹기 
# 목적: 순회해서 얻을 수 있는 양의 최댓값
from collections import deque
def build_tree(info, edges):
    tree = [[] for _ in range(len(info))]
    for edge in edges:
        tree[edge[0]].append(edge[1])
    return tree

def solution(info, edges):
    tree = build_tree(info, edges)
    max_sheep = 0
    q = deque([(0,1,0,set())])  #현재위치, 양 수, 늑대 수, 방문한 노드 집합
    
    while q:
        current, sheep, wolf, visited = q.popleft()
        max_sheep = max(max_sheep, sheep)
        visited.update(tree[current]) # 방문 갱신
        
        for next_node in visited:
            if info[next_node]:  # 1인경우 = 늑대인 경우
                if sheep > wolf + 1:  # 기존 늑대수 + 1이 sheep보다 적으면
                    q.append((next_node, sheep, wolf + 1, visited - {next_node}))
            else: # 양인 경우
                q.append((next_node, sheep + 1, wolf, visited - {next_node}))
    return max_sheep

 

 

 

 

 

 

 

 

 

 

문제 32) 길 찾기 게임 (카카오 2019)

https://school.programmers.co.kr/learn/courses/30/lessons/42892

 

프로그래머스

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

programmers.co.kr

문제 풀이 미완성

 

 

 

 

 

 

 

 

 

추천 문제 1) 입국 심사

https://school.programmers.co.kr/learn/courses/30/lessons/43238

 

프로그래머스

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

programmers.co.kr

문제 풀이 미완성

 

 

 

 

 

 

 

 

 

 

추천 문제 2) 트리 트리오 중간값

https://school.programmers.co.kr/learn/courses/30/lessons/68937

 

프로그래머스

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

programmers.co.kr

문제 풀이 미완성

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형

'TechStudy > CodingTest' 카테고리의 다른 글

chp11 그래프 (Graph)  (1) 2024.01.13
chp10 집합(set)  (0) 2024.01.06
chp8 해시(hash)  (1) 2023.12.13
chp6 스택(Stack), chp7 큐(Queue)  (4) 2023.12.07
백준 1차원 배열 10문제, 2차원 배열 단계 4문제 풀이  (1) 2023.11.30