[레퍼런스] 코딩테스트

JaeGwon-Lee·2025년 4월 8일

나만의 레퍼런스

목록 보기
4/4

프로그래머스 알고리즘 고득점 Kit

1. 정렬

출제빈도 : 높음 / 평균점수 : 높음

K번째수 - level 1

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

def solution(array, commands):
    answer = []
    for com in commands:
        i = com[0]; j = com[1]; k = com[2]
        arr = array[i-1:j]
        arr.sort()
        answer.append(arr[k-1])
    return answer
def solution(array, commands):
    answer = []
    for com in commands:
        i, j, k = com
        answer.append(sorted(array[i-1:j])[k-1])
    return answer

가장 큰 수 - level 2

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

def solution(numbers):
    answer = ''
    num = list(map(str, numbers))
    num.sort(key=lambda x: x*3, reverse=True)
    answer = ''.join(num)
    answer = str(int(answer))   # [0,0] -> "0"
    return answer

H-Index - level 2

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

def solution(citations):
    answer = 0
    n = len(citations)
    citations.sort(reverse=True)
    while n > 0:
        cnt = 0
        for cit in citations:
            if cit >= n:
                cnt += 1
            else:
                break
        if cnt >= n:
            answer = n
            break
        n -= 1
    return answer

2. 해시

출제빈도 : 높음 / 평균점수 : 보통

완주하지 못한 선수 - level 1

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

def solution(participant, completion):
    answer = ''
    for comp in completion:
        participant.pop(participant.index(comp))
    answer = participant[0]
    return answer

효율성 테스트 실패 -> 해시 사용

def solution(participant, completion):
    answer = ''
    dic = {}
    for p in participant:
        if p in dic:
            dic[p] += 1
        else:
            dic[p] = 1
    for c in completion:
        dic[c] -= 1
    for key, value in dic.items():
        if value > 0:
            answer = key
            break
    return answer

폰켓몬 - level 1

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

def solution(nums):
    answer = 0
    n = len(nums) / 2
    n_type = len(set(nums))
    if n_type >= n:
        answer = n
    else:
        answer = n_type
    return answer

전화번호 목록 - level 2

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

def solution(phone_book):
    phone_book.sort()
    for i in range(len(phone_book)-1):
        if phone_book[i] == phone_book[i+1][:len(phone_book[i])]:
            return False
    return True
def solution(phone_book):
    dic = {}
    for pb in phone_book:
        dic[pb] = 1
    for pb in phone_book:
        num = ""
        for n in pb:
            num += n
            if num in dic and num != pb:
                return False
    return True

의상 - level 2

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

def solution(clothes):
    clothes_dict = {}
    for cloth in clothes:
        if cloth[1] not in clothes_dict:
            clothes_dict[cloth[1]] = 1
        else:
            clothes_dict[cloth[1]] += 1
    answer = 1
    for value in clothes_dict.values():
        answer *= (value + 1)    # 해당 의상을 안입는 경우도 포함
    answer -= 1    # 아무것도 안입는 경우 제외
    return answer

베스트앨범 - level 3


3. 완전탐색

출제빈도 : 높음 / 평균점수 : 낮음

최소직사각형 - level 1

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

def solution(sizes):
    answer = 0
    w = []; h = []
    for size in sizes:
        w.append(max(size))
        h.append(min(size))
    answer = max(w) * max(h)
    return answer

모의고사 - level 1

https://school.programmers.co.kr/learn/courses/30/lessons/42840
풀이 실패 - 런타임

def solution(answers):
    answer = []
    length = len(answers)
    spj1 = [1,2,3,4,5]
    spj2 = [2,1,2,3,2,4,2,5]
    spj3 = [3,3,1,1,2,2,4,4,5,5]
    
    n = [0,0,0]
    for i, ans in enumerate(answers):
        if ans == spj1[i%5]:
            n[0] += 1
        if ans == spj2[i%8]:
            n[1] += 1
        if ans == spj3[i%10]:
            n[2] += 1
    
    if n[0] == max(n):
        answer.append(1)
    if n[1] == max(n):
        answer.append(2)
    if n[2] == max(n):
        answer.append(3)
    
    return answer

소수 찾기 - level 2

https://school.programmers.co.kr/learn/courses/30/lessons/42839
풀이 실패

from itertools import permutations

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

def solution(numbers):
    answer = 0
    nums = set()
    for i in range(1, len(numbers)+1):
        for num in permutations(list(numbers), i):
            nums.add(int(''.join(num)))
    for n in nums:
        if is_prime(n) == True:
            answer += 1
    return answer

카펫 - level 2

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

def solution(brown, yellow):
    answer = []
    # yellow = (w-2)*(h-2), brown = w*2+*(h-2)*2 = 2w+2h-4, w+h=(brown+4)/2
    sum_wh = (brown + 4) / 2
    for h in range(3, int(sum_wh/2)+1):    # h 최소 3
        w = sum_wh - h
        if h * w == brown + yellow:
            answer.append(w)
            answer.append(h)
            break
    return answer

관계식을 세워서 복잡하게 해결

def solution(brown, yellow):
    for i in range(1, yellow+1):    # i는 yellow 높이
        if yellow % i == 0:
            a = yellow / i + 2
            b = i + 2
            if a * b == brown + yellow:
                answer = [a,b]
                break
    return answer

노란색 카펫의 높이를 기준으로 잡으면 쉽게 해결 가능

피로도 - level 2

전력망을 둘로 나누기 - level 2

모음사전 - level 2


4. 깊이/너비 우선 탐색 (DFS/BFS)

출제빈도 : 높음 / 평균점수 : 낮음

타겟 넘버 - level 2

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

from itertools import combinations

def solution(numbers, target):
    answer = 0
    sum_num = sum(numbers)
    need_minus = int((sum_num - target) / 2)
    for i in range(1, need_minus + 1):
        for com in combinations(numbers, i):
            if sum(com) == need_minus:
                answer += 1
    return answer
def solution(numbers, target):
    answer = 0
    nodes = [0]
    for num in numbers:
        temp = []
        for parent in nodes:
            temp.append(parent + num)
            temp.append(parent - num)
        nodes = temp
    for node in nodes:
        if node == target:
            answer += 1
    return answer
#BFS 풀이
def solution(numbers, target):
    answer = 0
    leaves = [0]
    for num in numbers:
        tmp = []
        for parent in leaves:
            tmp.append(parent + num)
            tmp.append(parent - num)
        leaves = tmp
    for leaf in leaves:
        if leaf == target:
            answer += 1
    return answer

#DFS 풀이
def DFS(numbers, target, depth):
    answer = 0
    if depth == len(numbers):
        print(numbers)
        if sum(numbers) == target:
            return 1
        else: return 0
    else:
        answer += DFS(numbers, target, depth+1)
        numbers[depth] *= -1
        answer += DFS(numbers, target, depth+1)
        return answer

def solution(numbers, target):
    answer = DFS(numbers, target, 0)
    return answer

네트워크 - level 3

게임 맵 최단거리 - level 2

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

def solution(maps):
    answer = 0
    n = len(maps); m = len(maps[0])
    go_e = [0,1]; go_w = [0,-1]; go_s = [1,0]; go_n = [-1,0]
    leaves = [[1,1]]
    for i in range(2, n*m+1):
        temp = []
        for parent in leaves: 
            for go in [go_e, go_w, go_s, go_n]:
                gone = [x+y for x,y in zip(parent, go)]
                # 도착
                if gone[0] == n and gone[1] == m:
                    answer = i
                    return answer
                # 막힌 경우는 제외하기
                if (gone[0] == 0 or n+1) or (gone[1] == 0 or m+1):
                    continue
                elif maps[gone[0]][gone[1]] == 0:
                    continue
                else:
                    temp.append(gone)
        leaves = temp
        if leaves == []:
            answer = -1
            break
    return answer
def solution(maps):
    answer = 0
    n = len(maps); m = len(maps[0])
    dx = [1, -1, 0, 0]    # 남,북,동,서
    dy = [0, 0, 1, -1]
    nodes = [[1, 1]]
    for i in range(2, n*m+1):    # 최대 n*m번 이동
        temp = []
        for parent in nodes:
            for x, y in zip(dx,dy):
                child = [parent[0] + x, parent[1] + y]
                if child == [n, m]:    # 목적지에 도착한 경우
                    answer = i
                    return answer
                if not (1 <= child[0] <= n and 1 <= child[1] <= m):    # 맵을 이탈한 경우
                    continue
                if maps[child[0]-1][child[1]-1] == 0:    # 벽에 막힌 경우
                    continue
                temp.append(child)
        if len(temp) > 0:    # 갈수있는 길이 있는 경우
            nodes = temp
        else:
            answer = -1
    answer = -1
    return answer

효율성 테스트 실패

단어 변환 - level 3

아이템 줍기 - level 3

여행경로 - level 3

퍼즐 조각 채우기 - level 3


5. 스택/큐

출제빈도 : 보통 / 평균점수 : 높음

같은 숫자는 싫어 - level 1

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

def solution(arr):
    answer = []
    past = -1
    for a in arr:
        if a == past:
            continue
        else:
            answer.append(a)
            past = a
    return answer

기능개발 - level 2

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

def solution(progresses, speeds):
    answer = []
    while progresses:    # 리스트가 빌 때까지 반복
        progresses = [x+y for x,y in zip(progresses, speeds)]
        n = 0
        while progresses and progresses[0] >= 100:
            n += 1
            progresses.pop(0)
            speeds.pop(0)
        if n != 0:
            answer.append(n)
    return answer

올바른 괄호 - level 2

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

def solution(s):
    answer = True
    test = 0
    for tmp in s:
        if tmp == '(':
            test += 1
        else:
            test -= 1
        if test < 0:
            break
    if test != 0:
        answer = False
    return answer
# Stack 활용
def solution(s):
    answer = True
    stack = []
    for i in s:
        if i == '(':    # 왼쪽 괄호 stack에 보관
            stack.append(i)
        elif i == ')':    # stack의 왼쪽 괄호 한개 제거
            if stack:
                stack.pop()
            else:    # stack에 왼쪽 괄호가 없는데 오른쪽 괄호가 나오면 안됨
                return False
    if stack:    # 마지막에 stack이 비어야함
        return False
    else:
        return True

프로세스 - level 2

다리를 지나는 트럭 - level 2

주식가격 - level 2


6. 힙 (Heap)

출제빈도 : 보통 / 평균점수 : 높음

더 맵게 - level 2

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

def solution(scoville, K):
    answer = 0
    while 1:
        # 최소 스코빌이 K보다 작은데 음식이 부족한 경우
        if len(scoville) < 2 and scoville[0] < K:
            answer = -1
            break
        # 최소 스코빌이 K보다 큰 경우
        scoville.sort()
        if scoville[0] >= K:
            break
        # 새로운 음식 만들기
        new_s = scoville[0] + (scoville[1] * 2)
        scoville = scoville[2:]
        scoville.append(new_s)
        answer += 1
    return answer

효율성 테스트 실패 -> 힙 활용

# Heap 활용
# heapq.heapify(arr) : 리스트를 heap으로 변환
# heapq.heappop(arr) : heap에서 가장 작은 수 리턴
# heapq.heappush(arr, item) : heap에 삽입

import heapq
def solution(scoville, K):
    answer = 0
    heapq.heapify(scoville)
    
    while scoville[0] < K:
        if len(scoville) == 1:
            return -1
        mix = heapq.heappop(scoville) + (heapq.heappop(scoville) * 2)
        heapq.heappush(scoville, mix)
        answer += 1
    return answer

디스크 컨트롤러 - level 3

이중우선순위큐 - level 3


7. 탐욕법 (Greedy)

출제빈도 : 낮음 / 평균점수 : 낮음

체육복 - level 1

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

def solution(n, lost, reserve):
    lost_d = list(set(lost) - set(reserve))
    reserve_d = list(set(reserve) - set(lost))
    answer = n - len(lost_d)
    for l in lost_d:
        if l-1 in reserve_d:
            answer += 1
            reserve_d.remove(l-1)
        elif l+1 in reserve_d:
            answer += 1
            reserve_d.remove(l+1)
    return answer

조이스틱 - level 2

https://school.programmers.co.kr/learn/courses/30/lessons/42860
풀이 실패

def solution(name):
    
    # 알파벳 변경 횟수 (상하 이동) 
    spell_move = 0
    
    # 커서 이동 횟수, 이름의 길이 - 1 (좌우 이동)
    cursor_move = len(name) - 1  
    
    
    for i, spell in enumerate(name):
    	# 알파벳 변경 횟수, 위아래 중 최소 이동 값 (상하 이동)
        spell_move += min(ord(spell) - ord('A'), ord('Z') - ord(spell) + 1)
        
        # 해당 알파벳 다음부터 연속된 A 문자열 찾기
        next = i + 1
        while next < len(name) and name[next] == 'A':
            next += 1
            
        # 아래 3가지 경우 중 최소 이동 값으로 갱신
        # 1. 이전 커서 이동 값 (초기값 : 이름의 길이 - 1)
        # 2. 연속된 A의 왼쪽 시작
        # 3. 연속된 A의 오른쪽 시작
        cursor_move = min([ cursor_move, 2 * i + len(name) - next, i + 2 * (len(name) - next) ])
        
        
    # 조이스틱 조작 횟수 = 알파벳 변경 횟수(상하 이동) + 커서 이동 횟수(좌우 이동)    
    return spell_move + cursor_move

'''
A까지 이동시킨 후에 맨 뒤로 돌아가서 커서를 왼쪽으로 이동시키는 방법
- i까지 이동한 상태에서 ( i ) , 뒤이어 나올 A의 개수를 세어준다. (nextIndex = 연속된 A의 마지막 인덱스)
- 다시 맨 처음으로 돌아가 ( + i )
- 맨 끝에서부터 A가 나오기 전까지 이동시킨다 ( + len - nextIndex )
- 총 이동 = i + i + len - nextIndex

처음부터 맨뒤에서 시작한 후에 다시 맨 앞으로 돌아오는 방법
- 맨 끝부터 시작해서 A가 나오기 전까지 이동한다 ( len - nextIndex )
- 다시 맨 앞으로 돌아온다. ( + len - nextIndex )
- A가 나올 때까지 오른쪽으로 이동시키기 ( i )
- 총 이동 = len - nextIndex * 2 + i
'''

해설 1 : https://aiday.tistory.com/120
해설 2 : https://whynotworking.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4python-%EC%A1%B0%EC%9D%B4%EC%8A%A4%ED%8B%B1

큰 수 만들기 - level 2

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

def solution(number, k):
    answer = ''
    # 앞자릿수 최대 만들기
    f_num = number[:k+1]
    f_num = list(map(int, list(f_num)))    # 숫자 리스트로
    cut = f_num.index(max(f_num))    # 최대 앞자릿수 인덱스
    number = number[cut:]    # 인덱스로 자르기
    k -= cut
    
    # 뒤의 숫자보다 작으면 삭제
    if k > 0:
        count_k = k
        number = list(map(int, list(number)))    # 숫자 리스트로
        for i in range(k):
            for j in range(len(number)):
                if number[j] < number[j+1]:
                    number.pop(j)
                    count_k -= 1
                    break
        if count_k > 0:    # 삭제 안되고 남은 횟수
            number = number[:-count_k]    # 남은 횟수만큼 맨뒤 숫자 삭제
        number = ''.join(list(map(str, number)))    # 문자열로
    else:
        pass
    answer = number
    return answer

효율성 테스트 실패

def solution(number, k):
    # 뒤의 숫자보다 작으면 삭제
    count_k = k
    number = list(map(int, list(number)))    # 숫자 리스트로
    for i in range(k):
        for j in range(len(number)):
            if number[j] < number[j+1]:
                number.pop(j)
                count_k -= 1
                break
    if count_k > 0:    # 삭제 안되고 남은 횟수
        number = number[:-count_k]    # 남은 횟수만큼 맨뒤 숫자 삭제
    number = ''.join(list(map(str, number)))    # 문자열로
    return number

앞 부분이 필요 없었음
점수는 약간 올랐지만 효율성 테스트 실패
한 번 삭제하면 다시 처음부터 검사해서 효율이 안좋음
스택으로 푸는게 더 효율적

def solution(number, k):
    # 스택 선언
    stack = []
    
    # number의 길이만큼 for loop
    for num in number:
        # 1. 제거할 수 k가 남았고
        # 2. 스택에 값이 있고
        # 3. 스택의 마지막 값이 num보다 작다면
        # 제거 후 제거할 수 k를 1씩 감소 
        while k > 0 and stack and stack[-1] < num:
            stack.pop()
            k -= 1
        # 스택에 num 추가
        stack.append(num)
    
    # k가 남아있는 경우 - 테스트 케이스 number: "93939", k: 2, 출력: 999, 실제정답: 99
    if k != 0:
        stack = stack[:-k]
    
    # 배열을 문자열로 바꿔주고 반환
    return ''.join(stack)

해설 : https://aiday.tistory.com/116

구명보트 - level 2

섬 연결하기 - level 3

단속카메라 - level 3


8. 동적계획법 (Dynamic Programming)

출제빈도 : 낮음 / 평균점수 : 낮음

N으로 표현 - level 3

정수 삼각형 - level 3

등굣길 - level 3

사칙연산 - level 4

도둑질 - level 4


9. 이분탐색

출제빈도 : 낮음 / 평균점수 : 낮음

입국심사 - level 3

징검다리 - level 4


10. 그래프

출제빈도 : 낮음 / 평균점수 : 낮음

가장 먼 노드 - level 3

순위 - level 3

방의 개수 - level 5



프로그래머스 SQL 고득점 Kit

1. SELECT

출제빈도 : 낮음 / 평균점수 : 높음

조건에 부합하는 중고거래 댓글 조회하기 - level 1

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

SELECT B.TITLE
     , B.BOARD_ID
     , R.REPLY_ID
     , R.WRITER_ID
     , R.CONTENTS
     , DATE_FORMAT(R.CREATED_DATE, '%Y-%m-%d') AS CREATED_DATE
FROM USED_GOODS_BOARD AS B
JOIN USED_GOODS_REPLY AS R
    ON B.BOARD_ID = R.BOARD_ID
WHERE DATE_FORMAT(B.CREATED_DATE, '%Y-%m') = '2022-10'
ORDER BY R.CREATED_DATE, B.TITLE

과일로 만든 아이스크림 고르기 - level 1

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

SELECT F.FLAVOR
FROM FIRST_HALF AS F
JOIN ICECREAM_INFO AS I
    ON F.FLAVOR = I.FLAVOR
WHERE F.TOTAL_ORDER > 3000
    AND I.INGREDIENT_TYPE = 'fruit_based'
ORDER BY F.TOTAL_ORDER DESC

3월에 태어난 여성 회원 목록 출력하기 - level 2

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

SELECT MEMBER_ID
     , MEMBER_NAME
     , GENDER
     , DATE_FORMAT(DATE_OF_BIRTH, '%Y-%m-%d') AS DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE DATE_FORMAT(DATE_OF_BIRTH, '%m') = 3
     AND GENDER = 'W'
     AND TLNO IS NOT NULL
ORDER BY MEMBER_ID
WHERE MONTH(DATE_OF_BIRTH) = 3

재구매가 일어난 상품과 회원 리스트 구하기 - level 2

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

SELECT USER_ID
     , PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(*) > 1
ORDER BY USER_ID, PRODUCT_ID DESC

2. SUM, MAX, MIN

출제빈도 : 보통 / 평균점수 : 높음

가장 비싼 상품 구하기 - level 1

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

SELECT MAX(PRICE) AS MAX_PRICE
FROM PRODUCT

최댓값 구하기 - level 1

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

SELECT MAX(DATETIME) AS 시간
FROM ANIMAL_INS

가격이 제일 비싼 식품의 정보 출력하기 - level 2

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

SELECT PRODUCT_ID
     , PRODUCT_NAME
     , PRODUCT_CD
     , CATEGORY
     , MAX(PRICE) AS PRICE
FROM FOOD_PRODUCT

이렇게 실행하면 PRICE만 최댓값이 나오고 나머지 열은 첫번째 행이 나온다.

SELECT *
FROM FOOD_PRODUCT
WHERE PRICE = (SELECT MAX(PRICE) FROM FOOD_PRODUCT)
SELECT *
FROM FOOD_PRODUCT
ORDER BY PRICE DESC
LIMIT 1

최솟값 구하기 - level 2

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

SELECT DATETIME AS 시간
FROM ANIMAL_INS
WHERE DATETIME = (SELECT MIN(DATETIME) FROM ANIMAL_INS)
SELECT DATETIME AS 시간
FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1
SELECT MIN(DATETIME) AS 시간
FROM ANIMAL_INS

이 문제는 최솟값만 조회하므로 이렇게 써도된다.

동물 수 구하기 - level 2

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

SELECT COUNT(*) AS count
FROM ANIMAL_INS

중복 제거하기 - level 2

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

SELECT COUNT(DISTINCT NAME) AS count
FROM ANIMAL_INS
WHERE NAME IS NOT NULL
;

3. GROUP BY

출제빈도 : 보통 / 평균점수 : 보통

진료과별 총 예약 횟수 출력하기 - level 2

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

SELECT MCDP_CD AS 진료과코드
     , COUNT(*) AS 5월예약건수
FROM APPOINTMENT
WHERE DATE_FORMAT(APNT_YMD, '%Y-%m') = '2022-05'
GROUP BY MCDP_CD
ORDER BY 5월예약건수, 진료과코드

성분으로 구분한 아이스크림 총 주문량 - level 2

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

SELECT INGREDIENT_TYPE
     , SUM(TOTAL_ORDER) AS TOTAL_ORDER
FROM FIRST_HALF AS F
JOIN ICECREAM_INFO AS I
    ON F.FLAVOR = I.FLAVOR
GROUP BY INGREDIENT_TYPE
ORDER BY TOTAL_ORDER

자동차 종류 별 특정 옵션이 포함된 자동차 수 구하기 - level 2

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

SELECT CAR_TYPE
     , COUNT(*) AS CARS
FROM CAR_RENTAL_COMPANY_CAR
WHERE OPTIONS LIKE '%통풍시트%'
    OR OPTIONS LIKE '%열선시트%'
    OR OPTIONS LIKE '%가죽시트%'
GROUP BY CAR_TYPE
ORDER BY CAR_TYPE

입양 시각 구하기(1) - level 2

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

SELECT HOUR(DATETIME) AS HOUR
     , COUNT(*) AS COUNT
FROM ANIMAL_OUTS
WHERE HOUR(DATETIME) BETWEEN 9 AND 19
GROUP BY HOUR(DATETIME)
ORDER BY HOUR
;

가격대 별 상품 개수 구하기 - level 2

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

SELECT FLOOR(PRICE / 10000) * 10000 AS PRICE_GROUP
     , COUNT(*) AS PRODUCTS
FROM PRODUCT
GROUP BY PRICE_GROUP
ORDER BY PRICE_GROUP
;

4. IS NULL

출제빈도 : 낮음 / 평균점수 : 보통

경기도에 위치한 식품창고 목록 출력하기 - level 1

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

SELECT WAREHOUSE_ID
     , WAREHOUSE_NAME
     , ADDRESS
     , IFNULL(FREEZER_YN, 'N')
FROM FOOD_WAREHOUSE
WHERE ADDRESS LIKE '경기도%'
ORDER BY WAREHOUSE_ID

이름이 없는 동물의 아이디 - level 1

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

SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE ISNULL(NAME) = TRUE
ORDER BY ANIMAL_ID
WHERE NAME IS NULL

NULL 처리하기 - level 2

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

SELECT ANIMAL_TYPE
     , IFNULL(NAME, 'No name') AS NAME
     , SEX_UPON_INTAKE
FROM ANIMAL_INS
ORDER BY ANIMAL_ID

ROOT 아이템 구하기 - level 2

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

SELECT I.ITEM_ID
     , I.ITEM_NAME
FROM ITEM_INFO AS I
JOIN ITEM_TREE AS T
    ON I.ITEM_ID = T.ITEM_ID
WHERE T.PARENT_ITEM_ID IS NULL
ORDER BY ITEM_ID

5. JOIN

출제빈도 : 높음 / 평균점수 : 낮음

조건에 맞는 도서와 저자 리스트 출력하기 - level 2

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

SELECT B.BOOK_ID
     , A.AUTHOR_NAME
     , DATE_FORMAT(B.PUBLISHED_DATE, '%Y-%m-%d') AS PUBLISHED_DATE
FROM BOOK AS B
JOIN AUTHOR AS A
    ON B.AUTHOR_ID = A.AUTHOR_ID
WHERE B.CATEGORY = '경제'
ORDER BY PUBLISHED_DATE

상품 별 오프라인 매출 구하기 - level 2

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

SELECT P.PRODUCT_CODE
     , SUM(P.PRICE * S.SALES_AMOUNT) AS SALES
FROM PRODUCT AS P
JOIN OFFLINE_SALE AS S
    ON P.PRODUCT_ID = S.PRODUCT_ID
GROUP BY P.PRODUCT_CODE
ORDER BY SALES DESC, PRODUCT_CODE
;

없어진 기록 찾기 - level 3

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

SELECT O.ANIMAL_ID
     , O.NAME
FROM ANIMAL_OUTS AS O
LEFT JOIN ANIMAL_INS AS I
    ON O.ANIMAL_ID = I.ANIMAL_ID
WHERE I.ANIMAL_ID IS NULL
ORDER BY O.ANIMAL_ID

있었는데요 없었습니다 - level 3

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

SELECT I.ANIMAL_ID
     , I.NAME
FROM ANIMAL_INS AS I
JOIN ANIMAL_OUTS AS O
    ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.DATETIME > O.DATETIME
ORDER BY I.DATETIME

주문량이 많은 아이스크림들 조회하기 - level 4

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

SELECT F.FLAVOR
FROM FIRST_HALF AS F
JOIN JULY AS J
    ON F.FLAVOR = J.FLAVOR
GROUP BY F.FLAVOR
ORDER BY SUM(F.TOTAL_ORDER) + SUM(J.TOTAL_ORDER) DESC
LIMIT 3;
SELECT U.FLAVOR
FROM (SELECT * FROM FIRST_HALF
      UNION
      SELECT * FROM JULY) AS U
GROUP BY U.FLAVOR
ORDER BY SUM(U.TOTAL_ORDER) DESC
LIMIT 3;
SELECT F.FLAVOR
FROM FIRST_HALF AS F
JOIN (SELECT FLAVOR, SUM(TOTAL_ORDER) AS TOTAL_ORDER
      FROM JULY
      GROUP BY FLAVOR) AS J
    ON F.FLAVOR = J.FLAVOR
ORDER BY F.TOTAL_ORDER + J.TOTAL_ORDER DESC
LIMIT 3;

6. String, Date

출제빈도 : 낮음 / 평균점수 : 낮음

특정 옵션이 포함된 자동차 리스트 구하기 - level 1

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

SELECT *
FROM CAR_RENTAL_COMPANY_CAR
WHERE OPTIONS LIKE '%네비게이션%'
ORDER BY CAR_ID DESC

자동차 대여 기록에서 장기/단기 대여 구분하기 - level 1

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

SELECT HISTORY_ID
     , CAR_ID
     , DATE_FORMAT(START_DATE, '%Y-%m-%d') AS START_DATE
     , DATE_FORMAT(END_DATE, '%Y-%m-%d') AS END_DATE
     , CASE WHEN DATEDIFF(END_DATE, START_DATE) + 1 >= 30 THEN '장기 대여'
            ELSE '단기 대여'
            END AS RENT_TYPE
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE DATE_FORMAT(START_DATE, '%Y-%m') = '2022-09'
ORDER BY HISTORY_ID DESC

자동차 평균 대여 기간 구하기 - level 2

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

SELECT CAR_ID
     , ROUND(AVG(DATEDIFF(END_DATE, START_DATE) + 1), 1) AS AVERAGE_DURATION
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
HAVING AVERAGE_DURATION >= 7
ORDER BY AVERAGE_DURATION DESC, CAR_ID DESC

조건에 부합하는 중고거래 상태 조회하기 - level 2

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

SELECT BOARD_ID
     , WRITER_ID
     , TITLE
     , PRICE
     , CASE STATUS
        WHEN 'SALE' THEN '판매중'
        WHEN 'DONE' THEN '거래완료'
        WHEN 'RESERVED' THEN '예약중'
        END AS STATUS
FROM USED_GOODS_BOARD
WHERE DATE_FORMAT(CREATED_DATE, '%Y-%m-%d') = '2022-10-05'
ORDER BY BOARD_ID DESC

중성화 여부 파악하기 - level 2

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

     , NAME
     , CASE
       WHEN SEX_UPON_INTAKE LIKE '%Neutered%'
           OR SEX_UPON_INTAKE LIKE '%Spayed%' THEN 'O'
       ELSE 'X'
       END AS '중성화'
FROM ANIMAL_INS
;

카테고리 별 상품 개수 구하기 - level 2

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

SELECT SUBSTR(PRODUCT_CODE, 1, 2) AS CATEGORY
     , COUNT(*) AS PRODUCTS
FROM PRODUCT
GROUP BY SUBSTR(PRODUCT_CODE, 1, 2)
ORDER BY CATEGORY
;


Hacker Rank Algorithm

Easy

Plus Minus

https://www.hackerrank.com/challenges/one-week-preparation-kit-plus-minus/problem?isFullScreen=true&h_l=interview&playlist_slugs%5B%5D=preparation-kits&playlist_slugs%5B%5D=one-week-preparation-kit&playlist_slugs%5B%5D=one-week-day-one

def plusMinus(arr):
    n_pos = 0; n_neg = 0; n_zero = 0
    n = len(arr)
    
    for num in arr:
        if num > 0:
            n_pos += 1
        elif num < 0:
            n_neg += 1
        else:
            n_zero += 1
    
    answer_pos = n_pos / n
    answer_neg = n_neg / n
    answer_zero = n_zero / n
    
    print(f'{answer_pos:.6f}')
    print(f'{answer_neg:.6f}')
    print(f'{answer_zero:.6f}')

if __name__ == '__main__':
    n = int(input().strip())
    arr = list(map(int, input().rstrip().split()))
    plusMinus(arr)

Mini-Max Sum

https://www.hackerrank.com/challenges/one-week-preparation-kit-mini-max-sum/problem?isFullScreen=true&h_l=interview&playlist_slugs%5B%5D=preparation-kits&playlist_slugs%5B%5D=one-week-preparation-kit&playlist_slugs%5B%5D=one-week-day-one

def miniMaxSum(arr):
    arr.sort()
    
    arr_min = arr[:-1]
    arr_max = arr[1:]
    
    answer_min = sum(arr_min)
    answer_max = sum(arr_max)
    
    print(f'{answer_min} {answer_max}')

if __name__ == '__main__':
    arr = list(map(int, input().rstrip().split()))
    miniMaxSum(arr)

Time Conversion

https://www.hackerrank.com/challenges/one-week-preparation-kit-time-conversion/problem?isFullScreen=true&h_l=interview&playlist_slugs%5B%5D=preparation-kits&playlist_slugs%5B%5D=one-week-preparation-kit&playlist_slugs%5B%5D=one-week-day-one

def timeConversion(s):
    hour = s[:2]
    ampm = s[-2:]
    
    if s[:2] == '12':
        if ampm == 'AM':
            hour = str(int(hour) - 12)    # AM 12 to 0
        else:
            pass    # PM 12 to 12
    else:
        if ampm == 'AM':
            pass    # AM 1 to 1
        else:
            hour = str(int(hour) + 12)    # PM 1 to 13
    
    if len(hour) == 1:    # '0' to '00'
        hour = '0' + hour
    answer = hour + s[2:-2]
    
    return answer

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    s = input()
    result = timeConversion(s)
    fptr.write(result + '\n')
    fptr.close()

Lonely Integer

https://www.hackerrank.com/challenges/one-week-preparation-kit-lonely-integer/problem?isFullScreen=true&h_l=interview&playlist_slugs%5B%5D=preparation-kits&playlist_slugs%5B%5D=one-week-preparation-kit&playlist_slugs%5B%5D=one-week-day-two

import os

def lonelyinteger(a):
    if len(a) == 1:    # when list has only one element
        return a[0]
    
    a.sort()
    tmp = -1
    for i in a:
        if tmp == -1:
            tmp = i
        elif tmp != i:
            return tmp
        else:
            tmp = -1
    return tmp    # when last number is target

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    n = int(input().strip())
    a = list(map(int, input().rstrip().split()))
    result = lonelyinteger(a)
    fptr.write(str(result) + '\n')
    fptr.close()

Diagonal Difference

https://www.hackerrank.com/challenges/one-week-preparation-kit-diagonal-difference/problem?isFullScreen=true&h_l=interview&playlist_slugs%5B%5D=preparation-kits&playlist_slugs%5B%5D=one-week-preparation-kit&playlist_slugs%5B%5D=one-week-day-two

import os

def diagonalDifference(arr):
    l_to_r = 0
    r_to_l = 0
    index_lr = 0
    index_rl = len(arr) - 1
    
    for a in arr:
        l_to_r += a[index_lr]
        r_to_l += a[index_rl]
        index_lr += 1
        index_rl -= 1
    
    return abs((l_to_r - r_to_l))

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    n = int(input().strip())
    arr = []
    for _ in range(n):
        arr.append(list(map(int, input().rstrip().split())))
    result = diagonalDifference(arr)
    fptr.write(str(result) + '\n')
    fptr.close()

Intermediate

Balanced Brackets

https://www.hackerrank.com/challenges/one-week-preparation-kit-balanced-brackets/problem?isFullScreen=true&h_l=interview&playlist_slugs%5B%5D=preparation-kits&playlist_slugs%5B%5D=one-week-preparation-kit&playlist_slugs%5B%5D=one-week-day-five

import os

def isBalanced(s):
    stack = []
    for char in s:
        if char in ['(', '{', '[']:
            stack.append(char)
        else:
            if not stack:    # when stack emptied
                return 'NO'
            elif char == ')' and stack[-1] == '(':
                stack.pop()
            elif char == '}' and stack[-1] == '{':
                stack.pop()
            elif char == ']' and stack[-1] == '[':
                stack.pop()
            else:
                return 'NO'
    
    if len(stack) == 0:
        return 'YES'
    else:
        return 'NO'

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    t = int(input().strip())
    for t_itr in range(t):
        s = input()
        result = isBalanced(s)
        fptr.write(result + '\n')
    fptr.close()


Hacker Rank SQL

Easy

Revising the Select Query I

https://www.hackerrank.com/challenges/revising-the-select-query/problem?isFullScreen=true

SELECT *
FROM CITY
WHERE POPULATION > 100000
    AND COUNTRYCODE = 'USA';

Revising the Select Query II

https://www.hackerrank.com/challenges/revising-the-select-query-2/problem?isFullScreen=true

SELECT NAME
FROM CITY
WHERE COUNTRYCODE = 'USA'
    AND POPULATION > 120000;

Select All

https://www.hackerrank.com/challenges/select-all-sql/problem?isFullScreen=true

SELECT *
FROM CITY;

Intermediate

The PADS

https://www.hackerrank.com/challenges/the-pads/problem?isFullScreen=true

SELECT CONCAT(Name, "(", SUBSTRING(Occupation, 1, 1), ")")
FROM OCCUPATIONS
ORDER BY Name;

SELECT CONCAT("There are a total of ", COUNT(*), " ", LOWER(Occupation), "s.")
FROM OCCUPATIONS
GROUP BY Occupation
ORDER BY COUNT(*), Occupation;

Weather Observation Station 5

https://www.hackerrank.com/challenges/weather-observation-station-5/problem?isFullScreen=true

SELECT CITY
     , CHAR_LENGTH(CITY)
FROM STATION
ORDER BY CHAR_LENGTH(CITY), CITY
LIMIT 1;

SELECT CITY
    , CHAR_LENGTH(CITY)
FROM STATION
ORDER BY CHAR_LENGTH(CITY) DESC, CITY
LIMIT 1;

Binary Tree Nodes

https://www.hackerrank.com/challenges/binary-search-tree-1/problem?isFullScreen=true

SELECT N
     , CASE
       WHEN P IS NULL THEN 'Root'
       WHEN N IN (SELECT DISTINCT P FROM BST) THEN 'Inner'
       ELSE 'Leaf'
       END
FROM BST
ORDER BY N;


프로그래머스 문제 풀이 전략

1. 배열

삼각 달팽이 - level 2

거리두기 확인하기 - level 2


2. 문자열

튜플 - level 2

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

def solution(s):
    s = eval(s.replace('{','[').replace('}',']'))
    order = []
    for l in s:
        order.append(len(l)-1)
    answer = [0]*len(s)
    for i,o in enumerate(order):
        n = order.index(i)
        answer[i] = list(set(s[n]) - set(answer))[0]
    return answer

이진 변환 반복하기 - level 2

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

def solution(s):
    n_trans = 0
    n_zero = 0
    while s != '1':
        if '0' in s:
            n_zero += s.count('0')
            s = s.replace('0','')
        s = str(bin(len(s))[2:])
        n_trans += 1
    answer = [n_trans, n_zero]
    return answer

3. 재귀

하노이의 탑 - level 3

모음 사전 - level 2

호텔 방 배정 - level 4


4. 완전 탐색

카펫 - level 2

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

def solution(brown, yellow):
    for i in range(1, yellow+1):
        if yellow % i == 0:
            a = yellow/i+2; b = i+2
            if a * b - yellow == brown:
                answer = [a,b]
                break
    return answer

불량 사용자 - level 3

수식 최대화 - level 2


5. 정렬

H-index - level 2

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

def solution(citations):
    answer = 0
    for h in range(max(citations),0,-1):
        paper = 0
        for i in range(len(citations)):
            if citations[i] >= h:
                paper += 1
        if paper >= h:
            answer = h
            break
    return answer

6. 이진 탐색

입국심사 - level 3

순위 검색 - level 2

징검다리 건너기 - level 3


7. 해시

의상 - level 2

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

def solution(clothes):
    dict_clothes = {}
    for cloth in clothes:
        if cloth[1] not in dict_clothes:
            dict_clothes[cloth[1]] = [cloth[0]]
        else:
            dict_clothes[cloth[1]].append(cloth[0])
    answer = 1
    for value in dict_clothes.values():
        answer *= (len(value) + 1)
    answer -= 1
    return answer

베스트 앨범 - level 3


8. 동적 프로그래밍

정수 삼각형 - level 3

등굣길 - level 3

도둑질 - level 4


9. 스택과 큐

주식 가격 - level 2

기능 개발 - level 2


10. 그래프와 트리

가장 먼 노드 - level 3

순위 - level 3

길 찾기 게임 - level 3


11. 자료 구조

디스크 컨트롤러 - level 3

보석 쇼핑 - level 3

섬 연결하기 - level 3

가사 검색 - level 4


12. 구현

2개 이하로 다른 비트 - level 2

줄 서는 방법 - level 2


13. 구현 - 완전 탐색

여행 경로 - level 3

네트워크 - level 3

단어 변환 - level 3

게임 맵 최단거리 - level 3

경주로 건설 - level 3


14. 탐욕 알고리즘

조이스틱 - level 2

큰 수 만들기 - level 2

구명보트 - level 2

단속 카메라 - level 3



함수 정리

isalpha / isdigit

text.isalpha()    # 알파벳인지 확인
text.isdigit()    # 숫자인지 확인
text.isalnum()    # 알파벳 or 숫자인지 확인

int / float / str / list

int(3.14)    # 정수로 변환
> 3

float(3)    # 실수로 변환
> 3.0

str(3.14)    # 문자열로 변환
> "3.14"

list("3.14")    # 리스트로 변환
> ["3",".","1","4"]

나눗셈 / 몫 / 나머지

5 / 2    # 나눗셈
> 2.5
5 // 2    # 몫
> 2
5 % 2    # 나머지
> 1

pow / sqrt / log

import math

2**3    # 거듭 제곱
> 8
pow(2,3)
> 8
math.pow(2,3)
> 8.0

8**(1/2)    # 제곱근
> 2.0
8**(0.5)
> 2.0
math.sqrt(2)
> 2.0

math.log2(8)    # 밑이 2, 10, e인 로그함수
> 3.0
math.log10(100)
> 2.0
math.log(math.e)
> 1.0
math.log(25, 5)    # math.log(a, b) : 밑이 b인 로그함수
> 2.0

map

여러 개의 데이터를 받아서 각각의 요소에 함수를 적용한 결과를 반환

map(str, [1,2,3])
> <map at 0x1d3a22e34f0>
list(map(str, [1,2,3]))
> ["1", "2", "3"]

def square(x):
	return x**2
list(map(square, [1, 2, 3]))
> [1, 4, 9, 16, 25]

리스트에서 여러 변수로 할당

i, j, k = [1, 2, 3]

sort / sorted

num_list.sort()
num_list = sorted(num_list)

# 두번째 원소를 기준으로 정렬
num_str_list.sort(key=lambda x: x[1], reverse=True)

join

''.join(['a', 'b', 'c'])
> 'abc'

index

[4, 5, 6].index(4)
> 0

pop / remove

num_list = [1, 2, 3, 4]

num_list.pop()
> [1, 2, 3]
num_list.pop(2)
> [1, 2, 4]

num_list.remove(3)
> [1, 2, 4]

removed_list = num_list.remove(3)
type(removed_list)
> NoneType

dictionary 반복문

for key, value in dic.items():

for key in dic.keys():

for value in dic.values():

set

set([1, 1, 2, 3])
> {1, 2, 3}

# 교집합, 합집합, 차집합
set1 = set([1, 2, 3, 4])
set2 = set([3, 4, 5, 6])
set1 & set2
> {3, 4}
set1 | set2
> {1, 2, 3, 4, 5, 6}
set1 - set2
> {1, 2}

# 집합에 원소 추가
set1.add(5)
> {1, 2, 3, 4, 5}

# 빈 집합 만들기
empty_set = set()
type(empty_set)
> set
empty_set = {}
type(empty_set)
> dict

zip - 리스트 원소끼리 더하기

[x+y for x,y in zip(list1, list2)]

enumerate

for i, value in enumerate([1,2,3]):
    print(i, value)
> 0 1
  1 2
  2 3

ord / chr - 아스키코드

ord('A')
> 65
ord('Z')
> 90
ord('a')
> 97

chr(65)
> 'A'

# A에서 두 번째 후의 숫자
chr(ord('A') + 2)
> 'C'

# 알파벳 차이 (알파벳은 26개)
ord('Z') - ord('A')
> 25

permutations / combinations

from itertools import permutations

list(permutations([1, 2, 3], 2)
> [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

from itertools import combinations

list(combinations([1, 2, 3], 2))
> [(1, 2), (1, 3), (2, 3)]

f string

num = 0.4
print(f'{num:.4f}')
> 0.4000

에러 메시지

TypeError: 'int' object is not iterable

  • for문에서 iterable한 객체를 사용하지 않은 경우

TypeError: 'str' object cannot be interpreted as an integer

  • 문자형 데이터를 정수형처럼 사용한 경우

0개의 댓글