알고리즘 입문
개념 배우기직접 풀어보기
놀면 뭐 하니,
그냥 하는거야.

직접 풀어보자! 정렬 5문제

코딩냥

안녕, 나 코딩냥이다냥! 오늘 문제는 전부 medium 이라냥. 지금까지 푼 easy 와 달리 정렬 하나로 끝나지 않고, 정렬한 뒤에 뭔가를 더 해야 한다냥. 한 문제에 시간이 더 걸리는 게 정상이라냥. 조급해하지 말자냥.

medium 문제를 푸는 요령

  1. 먼저 정렬하면 뭐가 보이는지 생각한다냥
  2. 정렬한 상태를 종이에 적어본다냥
  3. 원하는 값이 몇 번째 자리에 있는지 찾는다냥
  4. 그제서야 코드를 쓴다냥

코드부터 쓰기 시작하면 오히려 오래 걸린다냥.

미션 1·오름차순 정렬7분

정수들을 작은 것부터 정렬해 한 줄에 공백으로 구분해 출력하는 문제다냥.

문제 풀러 가기

sorted() 를 쓰면 정렬은 끝이라냥. 남은 건 출력 형식이라냥.

리스트를 그냥 print() 하면 [1, 2, 3] 처럼 대괄호와 쉼표가 같이 나와서 오답이 된다냥. 공백으로 구분해 출력하려면 이렇게 쓴다냥.

print(*arr)

* 는 리스트를 풀어헤쳐서 하나씩 넘긴다는 뜻이라냥.

n = int(input())
arr = list(map(int, input().split()))

# 정렬해서 공백 구분으로 출력한다냥
미션 2·상위 k개10분

큰 값부터 k개를 출력하는 문제다냥.

문제 풀러 가기

두 가지를 붙이면 된다냥 — 큰 것부터 정렬(reverse=True)하고, 앞에서 k개를 슬라이싱한다냥.

첫 줄에 n 과 k 가 함께 주어진다는 걸 놓치지 말자냥.

n, k = map(int, input().split())
arr = list(map(int, input().split()))

# 큰 것부터 k개를 공백 구분으로 출력한다냥
미션 3·중앙값10분

정렬했을 때 정확히 가운데 오는 값을 출력하는 문제다냥. n 은 항상 홀수라냥.

문제 풀러 가기

가운데 인덱스는 n // 2 라냥. 슬래시 두 개라냥.

n / 2 를 쓰면 소수가 나와서 인덱스로 못 쓰고 에러가 난다냥.

확인직접 세어보자냥

n 이 5면 인덱스는 0 1 2 3 4 라서 가운데는 2번이고, 5 // 2 가 2라냥.

n 이 7이면? 0 1 2 3 4 5 6 이라서 3번이고 7 // 2 가 3이라냥. 맞다냥.

n = int(input())
arr = list(map(int, input().split()))

# 정렬한 뒤 가운데 값을 출력한다냥
미션 4·두 번째로 큰 수12분

서로 다른 값 중에서 두 번째로 큰 값을 출력하는 문제다냥.

문제 풀러 가기

오늘 배운 함정이 그대로 나오는 문제라냥.

5 5 3 이 주어지면 답은 뭐냥? 그냥 정렬해서 뒤에서 두 번째를 꺼내면 5 가 나오는데, 문제가 원하는 답은 3 이라냥.

"서로 다른 값 중에서"라고 했으니 중복을 먼저 없애야 한다냥.

set(arr) 을 쓰면 중복이 사라진다냥. 다만 set 은 순서가 없으니 그 다음에 다시 정렬해야 한다냥.

예시 입력 중에 중복이 들어있는 게 있다냥. 실행 버튼으로 꼭 확인하고 제출하자냥.

n = int(input())
arr = list(map(int, input().split()))

# 중복을 없애고, 정렬하고, 뒤에서 두 번째를 꺼낸다냥
미션 5·길이순 정렬15분

오늘의 마지막이자 제일 어려운 문제다냥. 단어를 길이가 짧은 것부터, 길이가 같으면 사전순으로 출력한다냥.

문제 풀러 가기

튜플 키를 쓸 차례라냥.

key=lambda s: (len(s), s)

앞의 len(s) 로 먼저 비교하고, 같을 때만 뒤의 s 로 비교한다냥.

key=len 만 쓰면 길이는 맞는데 같은 길이끼리 순서가 보장되지 않아 틀린다냥.

주의입력 읽는 법이 다르다냥

이 문제는 숫자가 아니라 여러 줄의 단어가 들어온다냥.

n = int(input())
words = [input().strip() for _ in range(n)]

.strip() 을 빼먹으면 줄바꿈이 단어에 붙어서 길이가 1씩 크게 나온다냥. 그러면 정렬 순서가 통째로 틀어진다냥.

n = int(input())
words = [input().strip() for _ in range(n)]

# 길이순, 같으면 사전순으로 한 줄에 하나씩 출력한다냥

다 풀었냥?

코딩냥

medium 다섯 문제를 다 풀었다면 정말 잘한 거라냥! 1번 빼고는 전부 "정렬 + 한 걸음" 이었다는 걸 봤냥? 정렬은 목적이 아니라 다음 걸음을 쉽게 만드는 준비라는 게 오늘의 핵심이라냥.

스스로 점검해보자냥

  • 다섯 문제를 전부 채점기에서 통과했냥?
  • sorted() 와 .sort() 중 아무거나 써도 되는 상황과 아닌 상황을 구분할 수 있냥?
  • key=lambda s: (len(s), s) 에서 튜플이 왜 필요한지 설명할 수 있냥?
  • 5 5 3 문제에서 왜 set() 이 필요했는지 설명할 수 있냥?
코딩냥

여기까지 왔으면 "정렬해두면 뭐가 쉬워지지?" 하고 먼저 생각하는 습관이 생겼을 거다냥. 그 습관이 앞으로 배울 탐색과 자료구조의 바탕이 된다냥. 수고했다냥~