문제 소개하나의 문자열 s가 주어졌을 때, 이를 여러 개의 부분 문자열로 나누되 모든 조각이 회문(palindrome)이 되도록 하려면 몇 번 잘라야 할까요? 이 문제에서는 필요한 최소 자르기(cut) 횟수를 구하는 것이 목표입니다.예를 들어, 문자열이 "ababba"라면 다음과 같이 두 번 잘라 세 개의 조각으로 나눌 수 있습니다.[aba | bb | a]"aba"도 회문이고, "bb"도 회문이며, 마지막 한 글자 "a" 역시 회문입니다. 따라서 정답은 2가
문제 소개N명의 아이들이 한 줄로 서 있고, 각 아이에게는 고유한 평점(rating) 값이 부여되어 있다고 가정해 보겠습니다. 우리는 다음 두 가지 조건을 만족하면서 아이들에게 사탕을 나누어 주어야 합니다.모든 아이는 최소한 사탕 한 개를 받아야 합니다.평점이 더 높은 아이는 자신의 양옆에 있는 이웃 아이들보다 많은 사탕을 받아야 합니다.이러한 조건을 만족하면서 나누어 주어야 할 사탕의 최소 개수를 구하는 것이 이 문제의 목표입니다.예시입력이 [1, 1, 3]이라면 출력은 4가 됩니다. 세 명의 아이는 각각 1개, 1개, 2개의 사
문제 정의2차원 평면 위에 여러 개의 점이 주어졌을 때, 같은 직선 위에 존재하는 점들의 최대 개수를 구하는 문제입니다.예를 들어 다음과 같은 점들이 있다고 가정해 보겠습니다.{(1,1), (3,2), (5,3), (4,1), (2,3), (1,4)}이 경우 직선 위에 놓일 수 있는 최대 점의 개수는 4개입니다.접근 방법이 문제는 두 점이 만드는 직선의 기울기(slope)를 이용해 해결할 수 있습니다. 세 점 (x1, y1), (x2, y2), (x3, y3)가 한 직선 위에 있으려면 다음 조건을 만족해야 합니다.(y3 − y2)
정렬된 배열이 어느 한 지점(피벗)을 기준으로 회전되어 있다고 가정해 보겠습니다. 피벗의 위치는 미리 알 수 없으며, 우리의 목표는 이 배열에서 최솟값을 찾는 것입니다. 예를 들어 배열이 [4,5,5,5,6,8,2,3,4]와 같다면 최솟값은 2입니다.이 문제의 핵심은 배열에 중복 요소가 포함될 수 있다는 점입니다. 중복이 없는 일반적인 회전 정렬 배열이라면 단순한 이진 탐색으로 O(log n)에 해결할 수 있지만, 중복이 존재하면 arr[low] == arr[mid]와 같은 모호한 상황이 발생해 어느 쪽 구간이 정렬되어 있는지 판별
문제 개요 정렬되지 않은 배열이 주어졌을 때, 정렬된 상태에서 인접한 두 요소 사이의 최대 차이(최대 간격)를 구하는 문제입니다. 배열에 포함된 요소가 2개 미만이라면 0을 반환합니다. 예를 들어 배열이 [12, 3, 9, 1, 17]이라면, 정렬한 결과는 [1, 3, 9, 12, 17]이 됩니다. 이때 인접 요소 간의 차이는 각각 2, 6, 3, 5이므로 최대 간격은 6입니다. 접근 방법: 버킷(Bucket) 활용 단순히 배열을 정렬한 뒤 인접 요소의 차이를 비교하면 O(n log n)의 시간이 필요합니다. 하지만 버킷을 이용하
문제 설명악마들이 이름이 P인 공주를 납치해 던전의 오른쪽 맨 아래 방에 가두었다는 이야기를 상상해 봅시다. 던전은 M행 × N열의 격자 형태 방으로 이루어져 있으며, 용감한 기사 K는 왼쪽 맨 위 방에서 출발해 공주를 구출하기 위해 던전을 돌파해 나가야 합니다.기사는 양의 정수로 표현되는 초기 체력(HP)을 가지고 시작합니다. 진행 도중 어느 시점에서든 체력이 0 이하로 떨어지면 그 자리에서 즉시 사망합니다.일부 방에는 악마가 지키고 있어 들어가는 순간 체력이 깎이고(음의 정수), 어떤 방은 비어 있거나 체력을 회복시켜 주는 마법
주식 거래 문제를 함께 해결해 보겠습니다. 배열의 i번째 요소가 i일째 되는 날의 특정 주식 가격을 나타낸다고 가정해 봅시다. 우리는 최대 이익을 찾는 알고리즘을 설계해야 하며, 이때 최대 k번의 거래만 허용됩니다.예를 들어 입력이 [3,2,6,4,0,3]이고 k = 2라면 출력은 7이 됩니다. 2일째 되는 날(가격이 2일 때)에 매수하고 3일째 되는 날(가격이 6일 때)에 매도하면 수익은 6 - 2 = 4입니다. 이후 5일째 되는 날(가격이 0일 때)에 다시 매수하고 6일째 되는 날(가격이 3일 때)에 매도하면 추가 수익은 3 -
문제 개요: 가장 짧은 회문 만들기문자열 s가 주어졌다고 가정해 보겠습니다. 우리는 이 문자열의 앞쪽에만 문자를 추가하여 회문(팰린드롬)으로 바꿀 수 있습니다. 이때 만들 수 있는 회문 중 가장 짧은 것을 찾는 것이 목표입니다.예를 들어 문자열이 "abcc"라면, 앞에 "ccb"를 추가하여 "ccbabcc"라는 가장 짧은 회문을 얻을 수 있습니다.핵심 아이디어: KMP 알고리즘의 LPS 배열 활용이 문제는 KMP 문자열 검색 알고리즘에서 사용되는 LPS(Longest Proper
기본적인 산술식의 결과를 계산하는 간단한 계산기를 C++로 만들어 보겠습니다. 이 계산기가 처리할 수식에는 여는 괄호 (와 닫는 괄호 ), 더하기(+), 빼기(-) 부호, 그리고 공백이 포함될 수 있습니다. 예를 들어 입력 문자열이 5 + 2 - 3이라면 계산 결과는 4가 됩니다. 문제 해결 접근 방법 이 문제는 스택(Stack) 자료구조를 활용하면 효율적으로 해결할 수 있습니다. 핵심은 세 개의 변수를 관리하는 것입니다. ret : 지금까지 누적된 계산 결과 sign : 현재 숫자 앞에 붙은 부호 (+1 또는 -1) num :
문제 개요숫자 n이 주어졌을 때, 0부터 n까지의 모든 음이 아닌 정수 안에서 숫자 1이 등장하는 총 횟수를 구하는 문제입니다. 예를 들어 입력이 15라면 출력은 8이 됩니다. 1이 포함된 숫자들은 [1, 10, 11, 12, 13, 14, 15]이며, 이 안에는 1이 총 8번 나타나기 때문입니다.접근 방법모든 숫자를 하나씩 확인하는 방법도 있지만, 입력이 커지면 매우 비효율적입니다. 대신 각 자릿수(일의 자리, 십의 자리, 백의 자리 등)별로 1이 몇 번 등장하는지 계산한 뒤 모두 더하면, n의 자릿수에 비례하는 시간 안에 빠르게
크기가 k인 슬라이딩 윈도우가 배열 nums의 왼쪽에서 오른쪽으로 한 칸씩 이동한다고 가정해 보겠습니다. 이때 우리는 윈도우 안에 있는 k개의 숫자만 볼 수 있으며, 윈도우가 이동할 때마다 각 위치에서 볼 수 있는 숫자들 중 최대값을 찾아야 합니다.예를 들어 입력이 [1, 3, -1, -3, 5, 3, 6, 8]이고 k가 3이라면, 윈도우는 다음과 같이 이동하며 각 단계의 최대값을 얻게 됩니다.윈도우 위치최대값13-1-35368313-1-35368313-1-35368313-1-35368513-1-35368613-1-353688문제
문제 개요0부터 9까지의 숫자로만 이루어진 문자열이 하나 주어지고, 목표값(target)이 주어집니다. 이때 숫자 사이에 이항 연산자 +, -, *를 삽입하여 목표값을 만들 수 있는 모든 가능한 조합을 반환해야 합니다.예를 들어 입력이 232이고 목표값이 8이라면, 정답은 [2*3+2, 2+3*2]가 됩니다. 두 식 모두 계산 결과가 8이기 때문입니다.풀이 접근 방법이 문제는 백트래킹(backtracking) 기법으로 해결할 수 있습니다. 각 위치에서 숫자를 잘라내고 세 가지 연산자를 차례로 적용하며 재귀적으로 탐색하는 방식입니다.
끊임없이 새로운 숫자가 유입되는 데이터 스트림이 있다고 가정해 봅시다. 이 스트림에서 지금까지 들어온 모든 숫자의 중앙값(median)을 빠르게 찾아내는 시스템을 만들어야 합니다.중앙값은 정렬된 리스트의 가운데 값입니다. 리스트 길이가 홀수라면 정확히 가운데 원소 하나를 그대로 반환하면 되고, 짝수라면 가운데 두 원소의 평균을 계산하면 됩니다.이 문제를 해결하기 위해 두 개의 메서드를 구현해야 합니다.addNum() — 스트림에 숫자를 추가하는 메서드findMedian() — 지금까지 추가된 모든 숫자의 중앙값을 반환하는 메서드해결
문제 개요n개의 풍선이 있으며, 각 풍선에는 0부터 n-1까지 번호가 붙어 있습니다. 각 풍선에는 nums 배열에 담긴 숫자가 하나씩 적혀 있고, 우리는 모든 풍선을 터뜨려야 합니다. i번째 풍선을 터뜨리면 nums[i-1] × nums[i] × nums[i+1]만큼의 코인을 얻게 되며, 풍선이 터진 후에는 i-1번과 i+1번 풍선이 서로 이웃하게 됩니다. 목표는 풍선을 가장 유리한 순서로 터뜨려 모을 수 있는 코인의 최댓값을 구하는 것입니다.예시로 이해하기입력이 [3, 1, 5, 7]이라면 정답은 148입니다. 터뜨리는 과정을 하
문제 소개 배열 nums가 주어졌을 때, 각 원소 기준으로 자신의 오른쪽에 있는 더 작은 숫자의 개수를 저장하는 새로운 배열 count를 구하는 것이 목표입니다. 즉, count[i]에는 nums[i]보다 작으면서 인덱스가 i보다 뒤에 있는 원소들의 개수가 들어갑니다. 예를 들어 입력이 [5,2,7,1]이라면 결과는 [2,1,1,0]이 됩니다. 5의 오른쪽에는 2와 1, 두 개의 더 작은 숫자가 있습니다. 2의 오른쪽에는 1 하나만 있습니다. 7의 오른쪽에는 1 하나가 있습니다. 1의 오른쪽에는 아무 숫자도 없으므로 0입니다.
문제 개요소문자 알파벳으로만 이루어진 문자열이 주어졌을 때, 모든 중복 문자를 제거하여 각 문자가 정확히 한 번만 나타나도록 만들어야 합니다. 이때 결과 문자열은 가능한 한 사전순(lexicographic)으로 가장 작은 순서가 되어야 합니다.예를 들어 입력이 abccb라면, 각 문자를 한 번씩만 포함하면서 사전순으로 가장 작은 결과인 abc를 반환해야 합니다.해결 접근 방법이 문제는 스택(stack), 빈도 카운트 맵, 스택 포함 여부 배열을 활용한 그리디 기법으로 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니다.현재 처리
문제 이해하기배열 nums와 하나의 숫자 n이 주어졌다고 가정해 봅시다. 배열에 요소를 몇 개 추가하여 [1, n] 범위(양 끝값 포함) 안의 모든 숫자를 배열 요소들의 합으로 표현할 수 있도록 만들어야 합니다. 이때 추가해야 하는 최소한의 요소 개수, 즉 패치(patch)의 수를 구하는 것이 문제입니다.예를 들어 배열이 [1, 4]이고 n = 7일 때를 살펴보겠습니다. 처음에는 부분합으로 1, 4, 5만 만들 수 있습니다. 하지만 여기에 2를 추가하면 배열은 [1, 2, 4]가 되고, 각 부분집합의 합은 1, 2, 3, 4, 5,
문제 소개 n개의 숫자로 이루어진 배열 x가 있다고 가정해 보겠습니다. 우리는 점 (0, 0)에서 출발하여 x[0]만큼 북쪽으로, x[1]만큼 서쪽으로, x[2]만큼 남쪽으로, x[3]만큼 동쪽으로 이동하며, 이후에도 같은 패턴으로 매 이동마다 방향을 반시계 방향으로 회전시켜 나갑니다. 이때 O(1)의 추가 공간만 사용하고 단 한 번의 순회(one-pass)로 경로가 자기 자신과 교차하는지 여부를 판별하는 알고리즘을 설계해야 합니다. 예를 들어 배열이 [3, 4, 2, 5]라고 한다면, 이동 경로는 다음 그림과 같습니다. 위 경우
문제 개요정수로 이루어진 데이터 스트림(a1, a2, ..., an, ...)이 입력된다고 가정해 보겠습니다. 우리는 지금까지 확인한 모든 숫자를 서로 겹치지 않는 구간(disjoint intervals)의 목록 형태로 요약해야 합니다.예를 들어, 입력 정수가 1, 3, 8, 2, 7, ... 순서로 들어온다면 각 시점의 요약 결과는 다음과 같습니다.[1, 1][1, 1], [3, 3][1, 1], [3, 3], [8, 8][1, 3], [8, 8][1, 3], [7, 8]2가 들어오면 기존의 [1, 1]과 [3, 3] 사이의 빈
이 문제에서는 숫자 n이 주어지며, 우리의 과제는 C++로 n번째 별 수(Star Number)를 찾는 프로그램을 작성하는 것입니다.별 수(Star Number)는 중심 육각별(centered hexagram), 즉 육각 별 모양으로 배열된 점들의 개수를 나타내는 특수한 수입니다.별 수의 예시로는 1, 13, 37, 73, 121 등이 있습니다.문제 이해를 위한 예시입력n = 5출력121해결 방법n번째 별 수를 구하기 위해 일반화된 공식을 사용할 수 있습니다. 먼저 몇 가지 항을 살펴보며 규칙을 찾아보겠습니다. 13 = 12 + 1