💻코딩테스트

[이코테_코딩테스트] 그리디 알고리즘

date
Jul 12, 2023
slug
coding-test-greedy-algorithm
author
status
Public
tags
Python
코딩테스트
summary
탐욕 알고리즘(greedy algorithm)에 대해 알아보자
type
Post
thumbnail
제목 없음.png
category
💻코딩테스트
updatedAt
Jul 13, 2023 02:24 PM

그리디 알고리즘(탐욕법)

  • 현재 상황에서 지금 당장 좋은 것만 고르는 방법
  • 일반적으로 그리디 알고리즘은 문제를 풀기 위한 최소한의 아이디어를 떠올릴 수 있는 능력을 요구
  • 그리디 해법은 정당성 분석이 매우 중요
    • 단순히 가장 좋아 보이는 것을 반복적으로 선택해도 최적의 해를 구할 수 있는지 검토하는 과정이 필요!
 

[문제] 루트 노드부터 시작하여 거쳐 가는 노드 값의 합을 최대로 만들고 싶다.

Q1. 최적의 해는 무엇인가?

notion image
5 → 7 → 9 = 21

Q2. 단순히 매 상황에서 가장 큰 값만 고른다면?

  • 루트 하위 노드 7, 10, 8 중 10 선택
  • 10 하위 4, 3 중 3 선택
5 → 10 → 4 = 19
 

Q2 방식처럼 매 상황에서 당장 좋은 것만 선택하는 방식이 그리디 알고리즘

  • 일반적인 상황에서 그리디 알고리즘은 최적의 해를 보장할 수 없을 때가 많다.
  • 코딩 테스트에서는 미리 출제자가 답을 정해놓고 만드는 경우가 많음
    • 그리디 문제는 탐욕법으로 얻은 해가 최적의 해가 되는 상황에서, 이를 추론할 수 있어야 풀린다.
 

[문제] 거스름 돈

Q. 당신은 음식점의 계산을 도와주는 점원입니다. 카운터에서 거스름돈으로 사용할 500원, 100원, 50원, 10원짜리 동전이 무한히 존재한다고 가정합니다. 손님에게 거슬러 주어야 할 돈이 N원일 때 거슬러 주어야 할 동전의 최소 개수를 구하세요. 단, 거슬러 줘야 할 돈 N은 항상 10의 배수입니다.

 

[문제] 거스름 돈 - 해결 아이디어

  • 최적의 해를 빠르게 구하기 위해 가장 큰 화폐 단위부터 거슬러 주면 된다.
  • N원을 거슬러 줘야 할 때, 가장 먼저 500원으로 거슬러 줄 수 있는만큼 거슬러 준다.
    • 이후 100원, 50원, 10원을 차례대로 거슬러 준다.

N = 1,260일 때의 예시

  • [Step 0] 초기 단계 - 남은 돈 : 1,260
  • [Step 1] 500원 거슬러 준 이후 - 남은 돈 : 260
  • [Step 2] 100원 거슬러 준 이후 - 남은 돈 : 60
  • [Step 3] 50원 거슬러 준 이후 - 남은 돈 : 10
  • [Step 4] 10원 거슬러 준 이후 - 남은 돈 : 0
Step
남은 돈
손님 500원 개수
손님 100원 개수
손님 50원 개수
손님 10원 개수
Step 0
1,260
0
0
0
0
Step 1
260
2
0
0
0
Step 2
60
2
2
0
0
Step 3
10
2
2
1
0
Step 4
0
2
2
1
1
 

[문제] 거스름 돈 - 정당성 분석

  • 가장 큰 화폐 단위부터 돈을 거슬러 주는 것이 최적의 해를 보장하는 이유는?
    • 가지고 있는 동전 중 큰 단위가 항상 작은 단위의 배수
    • 작은 단위의 동전들을 종합해 다른 해가 나올 수 없다.
  • 만약 800원을 거슬러 줘야 하는데 화폐 단위가 500원, 400원, 100원이라면?
    • 위 방법으로 푼다면 500원 1 개 + 100원 3 개
    • 최적의 해는? → 400원 2 개
    • 큰 단위(500원)이 작은 단위(400원)의 배수가 아니다! → 최적의 해를 보장할 수 없다!
  • 이처럼 문제 풀이를 위한 최소한의 아이디어를 떠올리고 정당한지 검토할 수 있어야 함!
 

[문제] 거스름 돈 - 답안 예시 (Python)

n = 1260 count = 0 # 큰 단위부터 확인 array = [500, 100, 50, 10] for coin in array: count += n // coin # 해당 화폐로 거슬러 줄 수 있는 동전 개수 n %= coin # 거슬러 준 후 남은 돈 print(count)
[문제] 거스름 돈 - 답안 예시 (Java)
public class Main { public static void main(String[] args) { int n = 1260; inc cnt = 0; int [] coinTypes = {500, 100, 50, 10}; for (int i = 0; i < 4; i++) { cnt += n / coinTypes[i]; n %= coinTypes[i]; } System.out.println(cnt); } }

[문제] 거스름 돈 - 시간 복잡도 계산

  • 화폐의 종류가 K라고 할 때, 시간 복잡도는 O(K)
  • 거슬러줘야 하는 금액과는 무관, 동전의 종류에만 영향을 받는다.
 
 

이 글은 유튜브 “동빈나” 채널의 “(이코테 2021 강의 몰아보기) 2. 그리디 & 구현” 영상을 보고 작성하였습니다.