음이 아닌 정수 목록 a1, a2, ..., an과 목표값 S가 주어졌다고 가정해 보겠습니다. 우리에게는 +와 -라는 두 가지 기호가 있으며, 각 정수마다 둘 중 하나를 선택해 부호를 지정해야 합니다. 이때 정수들의 합이 목표값 S와 같아지도록 기호를 배정하는 방법이 총 몇 가지인지 구하는 것이 이 문제의 목표입니다.예를 들어 숫자가 [1,1,1,1,1]이고 S = 3이라면 출력은 5가 됩니다. 가능한 조합은 다음과 같습니다.-1 + 1 + 1 + 1 + 1 = 3+1 - 1 + 1 + 1 + 1 = 3+1 + 1 - 1 + 1 +
원형 배열(circular array)이 있다고 가정해 봅시다. 여기서 원형이란 배열의 마지막 요소 다음에 다시 첫 번째 요소가 오는 구조를 의미합니다. 이러한 배열에서 모든 요소에 대해 다음 큰 수(Next Greater Number)를 찾아 출력해야 합니다.여기서 어떤 수 x의 다음 큰 수란, 배열을 순회하는 방향으로 x 바로 다음에 처음 등장하는 더 큰 수를 말합니다. 원형 배열이므로 끝에 도달하면 다시 처음부터 탐색을 이어갈 수 있습니다. 만약 더 큰 수가 존재하지 않는다면 결과값은 -1이 됩니다.예를 들어 입력 배열이 [1
문제 개요서로 다른 액면가를 가진 동전들과 하나의 목표 금액이 주어졌을 때, 그 금액을 만들 수 있는 조합(combination)의 개수를 계산하는 함수를 작성해야 합니다. 이때 각 종류의 동전은 무한개 있다고 가정합니다.예를 들어 목표 금액이 5이고 동전의 액면가가 [1, 2, 5]라면, 다음과 같이 총 네 가지 조합이 존재합니다.(1+1+1+1+1), (1+1+1+2), (1+2+2), (5)풀이 접근 방식 (동적 계획법)이 문제는 대표적인 동적 계획법(DP) 유형입니다. 핵심은 바깥쪽 루프를 동전 종류 기준으로 돌려야 순서만
정렬된 정수 배열이 있고, 모든 요소는 정확히 두 번씩 나타나지만 단 하나의 요소만 딱 한 번 나타난다고 가정해 보겠습니다. 이때 우리가 찾아야 할 것은 바로 이 한 번만 등장하는 요소입니다.예를 들어 배열이 [1, 1, 2, 3, 3, 4, 4, 8, 8]과 같다면, 두 번씩 짝지어 등장하지 않는 유일한 값은 2이므로 출력 결과는 2가 됩니다.문제 해결 접근 방법이 문제는 XOR(배타적 논리합) 연산의 특성을 활용하면 매우 간단하게 해결할 수 있습니다. XOR 연산은 다음과 같은 중요한 성질을 가집니다.같은 숫자끼리 XOR하면 결
정수 배열 nums와 정수 k가 주어졌을 때, 원소들의 합이 정확히 k와 같은 연속된 부분 배열(subarray)의 총 개수를 구하는 문제입니다. 예를 들어 배열이 [1, 1, 1]이고 k가 2라면, 답은 2가 됩니다. 첫 두 원소로 이루어진 [1, 1]과 마지막 두 원소로 이루어진 [1, 1], 이렇게 두 가지 경우가 해당되기 때문입니다. 접근 방법 — 누적 합(Prefix Sum)과 해시 맵 모든 부분 배열을 일일이 확인하는 브루트 포스 방식은 O(n²)의 시간이 소요됩니다. 누적 합과 해시 맵을 함께 사용하면 이를 O(n)으로
두 개의 문자열 s1과 s2가 주어졌을 때, s2 안에 s1의 순열(permutation)이 존재하면 true를 반환하는 함수를 작성해야 합니다. 즉, 첫 번째 문자열의 순열 중 하나가 두 번째 문자열의 부분 문자열(substring)로 나타나는지를 판별하는 문제입니다.예를 들어 s1 = abc이고 s2 = findcab라고 가정해 보겠습니다. 이 경우 결과는 true가 됩니다. 왜냐하면 abc의 순열 중 하나인 cab가 s2 안에 그대로 포함되어 있기 때문입니다.문제 해결 접근 방법이 문제는 슬라이딩 윈도우(Sliding Wind
문제 설명두 단어 w1과 w2가 주어졌을 때, 매 단계마다 두 문자열 중 하나에서 문자 하나를 삭제하여 두 단어를 완전히 같게 만들어야 합니다. 이때 필요한 최소 단계 수를 구하는 것이 목표입니다.예를 들어 입력이 sea와 eat이라면 출력은 2가 됩니다. w1에서 s를 삭제해 ea로 만들고, w2인 eat에서 t를 삭제해 ea로 만들면 두 문자열이 같아지기 때문입니다.해결 접근 방법이 문제는 동적 계획법(Dynamic Programming)으로 효율적으로 해결할 수 있습니다. dp[i][j]를 s1의 앞 i개 문자와 s2의 앞 j
문제 개요정렬된 배열과 두 개의 정수 k, x가 주어졌을 때, 배열에서 x에 가장 가까운 k개의 요소를 찾는 문제입니다. 결과는 반드시 오름차순으로 정렬되어야 하며, 거리가 같은 경우(동률)에는 항상 더 작은 값을 우선적으로 선택합니다.예를 들어 입력 배열이 [1,2,3,4,5]이고 k = 4, x = 3이라면, 출력은 [1,2,3,4]가 됩니다.접근 방법: 이진 탐색 활용배열이 이미 정렬되어 있으므로, 이진 탐색(Binary Search)을 사용하면 O(log(n-k)) 시간 복잡도로 효율적으로 해결할 수 있습니다. 알고리즘은 다
문제 개요 정렬되지 않은 정수 배열이 하나 주어졌을 때, 가장 길게 증가하는 부분 수열(Longest Increasing Subsequence, LIS)의 개수를 구하는 것이 목표입니다. 예를 들어 입력이 [1, 3, 5, 4, 7]이라면, 길이가 4인 증가 부분 수열은 [1, 3, 5, 7]과 [1, 3, 4, 7] 두 가지가 존재하므로 정답은 2가 됩니다. 접근 방법: 동적 계획법 이 문제는 동적 계획법(Dynamic Programming)을 활용하면 효율적으로 해결할 수 있습니다. 핵심 아이디어는 각 인덱스마다 다음 두 가지
문제 개요비어 있지 않은 단어 목록이 주어졌을 때, 가장 많이 등장하는 상위 k개의 단어를 찾아야 합니다. 결과는 빈도수가 높은 순서부터 낮은 순서대로 정렬해야 하며, 두 단어의 빈도수가 같다면 알파벳 순서상 앞에 오는 단어를 먼저 배치합니다.예를 들어 입력 배열이 [the, sky, is, blue, the, weather, is, comfortable]이고 k가 3이라면 결과는 [is, the, blue]입니다. the와 is는 각각 2번 등장해 최상위 두 자리를 차지하고, 나머지 단어들은 모두 1번씩 등장했으므로 그중 알파벳
문제 개요 정수 배열 nums와 양의 정수 k가 주어졌을 때, 이 배열을 각 부분 집합의 합이 서로 같도록 k개의 비어 있지 않은 부분 집합으로 나눌 수 있는지 확인하는 것이 목표입니다. 예를 들어 배열이 [4, 3, 2, 3, 5, 2, 1]이고 k = 4라고 가정해 보겠습니다. 이 경우 결과는 True입니다. 배열을 [[5], [1, 4], [2, 3], [2, 3]]처럼 네 개의 그룹으로 나누면 각 그룹의 합이 모두 5로 동일하기 때문입니다. 해결 전략: 비트마스크 동적 계획법(DP) 부분 집합 분할 문제는 가능한 조합의 수
이진 탐색 트리(Binary Search Tree)가 하나 있다고 가정해 봅시다. 우리는 단 하나의 메서드만 작성해야 하며, 이 메서드는 매개변수로 전달된 값을 트리에 삽입하는 역할을 합니다. 중요한 점은 삽입 연산이 끝난 후에도 트리가 여전히 BST의 성질을 유지해야 한다는 것입니다. 예를 들어 다음과 같은 트리가 있다고 합시다. 여기에 5를 삽입하면 트리는 아래와 같이 변합니다. 접근 방법 이 문제는 다음 단계를 따라 해결할 수 있습니다. 삽입 메서드는 재귀적으로 동작하며, insert()라는 이름으로 값 v를 인자로 받
문제 개요두 개의 문자열 w1과 w2가 주어졌을 때, 각 단계마다 어느 한쪽 문자열에서 문자를 하나씩 삭제할 수 있다고 가정해 봅시다. 이때 두 문자열을 완전히 동일하게 만들기 위해 삭제해야 하는 문자들의 ASCII 값 합계의 최솟값을 구하는 것이 이번 문제의 목표입니다.예를 들어 입력이 sea와 eat이라면 출력은 231이 됩니다. 그 이유는 다음과 같습니다.w1에서 s(ASCII 115)를 삭제하면 ea가 됩니다.w2에서 t(ASCII 116)를 삭제하면 ea가 됩니다.두 문자열이 같아지며, 총합은 115 + 116 = 231로
문제 설명양의 정수로 이루어진 배열 nums가 주어졌을 때, 부분 배열에 포함된 모든 원소의 곱이 k보다 작은 연속(contiguous) 부분 배열의 개수를 세어 출력하는 문제입니다.예를 들어 입력이 [10, 5, 2, 6]이고 k = 100이라면 정답은 8이며, 조건을 만족하는 부분 배열은 다음과 같습니다.[10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]풀이 접근: 슬라이딩 윈도우모든 부분 배열을 하나씩 검사하는 브루트 포스 방식은 비효율적입니다. 대신 슬라이딩 윈도우(투 포인터)
문제 개요일일 기온 리스트 T가 주어졌을 때, 각 날짜마다 현재보다 더 따뜻한 기온이 나타날 때까지 며칠을 기다려야 하는지를 담은 리스트를 반환하는 문제입니다. 만약 이후에 더 따뜻한 날이 존재하지 않는다면 해당 위치에는 0을 저장합니다.예를 들어 T = [73, 74, 75, 71, 69, 72, 76, 73]이라면 결과는 [1, 1, 4, 2, 1, 1, 0, 0]이 됩니다. 첫 번째 날(73도)은 바로 다음 날(74도)에 더 따뜻해지므로 1이고, 세 번째 날(75도)은 이후 기온이 잠시 내렸다가 여섯 번째 날(76도)에 처음으
문제 개요소문자로만 이루어진 문자열 S가 주어졌다고 가정해 보겠습니다. 우리의 목표는 각 문자가 최대 하나의 조각에만 등장하도록 문자열을 최대한 많은 조각으로 나누고, 각 조각의 길이를 정수 리스트 형태로 반환하는 것입니다.예를 들어 문자열이 ababcbacadefegdehijhklij라면 출력은 [9, 7, 8]입니다. 문자열은 ababcbaca, defegde, hijhklij 세 부분으로 나뉘며, 모든 문자가 자신이 속한 조각 안에만 존재하기 때문입니다.반면 ababcbacadefegde, hijhklij처럼 두 조각으로 나누
문제 개요배열 arr이 [0, 1, ..., arr.length - 1]의 순열(permutation)로 주어졌다고 가정해 봅시다. 이 배열을 여러 개의 청크(chunk), 즉 부분 구간으로 나눈 뒤, 각 청크를 개별적으로 정렬하고 다시 이어 붙였을 때 전체가 정렬된 배열이 되도록 해야 합니다.예를 들어 배열이 [1, 0, 2, 3, 4]라면 출력은 4가 됩니다. 배열을 [1, 0]과 [2, 3, 4] 두 개의 파티션으로 나눌 수도 있지만, [1, 0], [2], [3], [4]처럼 네 개로 나누는 것도 가능합니다. 이렇게 만들 수
C++ STL에서 deque의 emplace( ) 함수가 어떤 기능을 수행하는지 자세히 알아보겠습니다.덱(Deque)이란?덱(Double Ended Queue, 양방향 큐)은 양쪽 끝에서 모두 요소를 추가하거나 제거할 수 있는 시퀀스 컨테이너입니다. 일반적인 큐(Queue) 자료구조는 데이터를 뒤쪽(END)에서만 삽입하고 앞쪽(FRONT)에서만 삭제할 수 있습니다. 버스 정류장의 줄을 떠올려 보면 쉽게 이해할 수 있습니다. 새로운 사람은 항상 줄의 맨 뒤에서만 들어오고, 맨 앞에 서 있는 사람부터 차례로 빠져나갑니다. 반면 양방향
이 글에서는 C++ STL에서 덱(deque)의 crend() 함수가 어떤 기능을 수행하는지 예제와 함께 자세히 살펴보겠습니다. 덱(Deque)이란? 덱(Double Ended Queue, 데크)은 양쪽 끝(front와 back)에서 모두 데이터의 삽입과 삭제, 즉 확장과 축소가 가능한 시퀀스 컨테이너입니다. 일반적인 큐(queue) 자료구조는 데이터를 뒤(rear)에만 삽입할 수 있고 앞(front)에서만 삭제할 수 있습니다. 버스 정류장의 줄을 예로 들어 보면, 새로 온 사람은 줄의 맨 뒤에만 추가되고 맨 앞에 서 있는 사람이
이 글에서는 C++에서 fread() 함수가 어떻게 동작하는지 알아봅니다. 아울러 fread()에 전달되는 다양한 매개변수와 이 함수가 반환하는 값에 대해서도 자세히 살펴보겠습니다. fread()는 스트림(stream)에서 데이터 블록을 읽어오는 C++의 내장 함수입니다. 이 함수는 스트림에서 각각 size 바이트 크기를 가진 객체를 count개만큼 읽어 버퍼 메모리에 저장하며, 읽기가 완료되면 위치 포인터(position pointer)는 읽어온 총 바이트 수만큼 앞으로 이동합니다. 읽기가 성공하면 읽어온 바이트 수는 size ×