문제 개요이번 글에서는 ProductOfNumbers라는 클래스를 구현해 보겠습니다. 이 클래스는 스트림으로 들어오는 숫자들을 관리하면서, 다음 두 가지 메서드를 지원해야 합니다.add(int num): 현재 숫자 목록의 맨 뒤에 num을 추가합니다.getProduct(int k): 현재 목록에서 마지막 k개 숫자의 곱을 반환합니다.현재 목록에는 항상 최소 k개 이상의 숫자가 들어 있다고 가정할 수 있습니다.동작 예시예를 들어 다음과 같은 순서로 메서드를 호출한다고 가정해 보겠습니다.add(3), add(0), add(2), add
문제 개요events[i] = [startDayi, endDayi] 형태의 이벤트 배열이 주어진다고 가정해 봅시다. i번째 이벤트는 startDayi에 시작하여 endDayi에 종료되며, d가 startDayi부터 endDayi 사이(양 끝 포함)에 있는 임의의 날짜에 해당 이벤트에 참석할 수 있습니다. 단, 같은 날에는 하나의 이벤트만 참석 가능하다는 조건이 있습니다. 우리의 목표는 참석할 수 있는 이벤트의 최대 개수를 구하는 것입니다.예를 들어, 입력이 [[1,4], [4,4], [2,2], [3,4], [1,1]]이라면 출력은
문제 개요슈퍼마켓에서 세일 행사를 진행한다고 가정해 보겠습니다. 이 행사에서는 매 n번째 고객에게 결제 금액에 대한 할인이 적용됩니다. 슈퍼마켓에는 여러 상품이 있으며, i번째 상품의 ID는 products[i], 해당 상품의 단위당 가격은 prices[i]입니다.시스템은 도착한 고객 수를 계속 집계하다가, n번째 고객이 도착하면 그 고객의 청구서에 할인을 적용합니다. 할인이 적용된 후에는 다시 고객 수를 처음부터 집계합니다. 고객은 각 상품을 원하는 수량만큼 주문할 수 있으며, product[i]는 고객이 주문한 i번째 상품의 I
문제 개요문자 a, b, c로만 이루어진 문자열 s가 주어졌을 때, 이 세 문자가 각각 최소 한 번 이상 등장하는 부분 문자열의 개수를 구하는 문제입니다.예를 들어 문자열이 abcabc라면, 조건을 만족하는 부분 문자열은 총 10개입니다.인덱스 0부터 시작: abc, abca, abcab, abcabc인덱스 1부터 시작: bca, bcab, bcabc인덱스 2부터 시작: cab, cabc인덱스 3부터 시작: abc즉, 4 + 3 + 2 + 1 = 10개가 됩니다.접근 방법: 슬라이딩 윈도우모든 부분 문자열을 일일이 검사하면 O(n²
문제 소개 0부터 n-1까지 번호가 매겨진 n개의 이진 트리 노드가 주어졌다고 가정해 봅시다. 각 노드 i는 두 개의 자식을 가질 수 있으며, 왼쪽 자식은 leftChild[i], 오른쪽 자식은 rightChild[i]로 표현됩니다. 이때 주어진 모든 노드가 정확히 하나의 유효한 이진 트리를 이루는 경우에만 true를 반환해야 합니다. 노드 i에 왼쪽 자식이 없으면 leftChild[i]는 -1이 되고, 마찬가지로 오른쪽 자식이 없으면 rightChild[i]는 -1입니다. 또한 이 문제에서 노드는 실제 값을 가지지 않으며 노드 번
정수 num이 주어졌을 때, 곱이 num + 1 또는 num + 2가 되는 두 정수 중 절댓값 차이가 가장 작은 두 수를 찾는 것이 이 문제의 목표입니다. 두 정수는 순서에 상관없이 반환하면 됩니다.예를 들어 입력값이 8이라면 결과는 [3, 3]입니다. num + 1 = 9인 경우 가장 가까운 약수 쌍은 3과 3이며, num + 2 = 10인 경우에는 2와 5입니다. 두 경우를 비교했을 때 3과 3의 차이(0)가 더 작으므로 [3, 3]이 정답이 됩니다.문제 해결 접근 방식이 문제는 각 숫자에 대해 제곱근 범위까지 탐색하면서 가장
이진 트리의 루트(root)와 첫 번째 노드가 head인 연결 리스트가 주어졌을 때, 연결 리스트의 모든 요소가 이진 트리에서 루트부터 아래 방향으로 이어지는 어떤 경로와 일치하면 True를, 그렇지 않으면 False를 반환해야 합니다.예를 들어 다음과 같은 이진 트리가 있다고 가정해 보겠습니다.이때 연결 리스트가 [1, 4, 2, 6]이라면, 이 값들이 트리의 한 하향 경로에 순서대로 존재하므로 출력 결과는 true가 됩니다.문제 해결 접근 방법이 문제는 재귀 호출과 메모이제이션(memoization)을 활용하여 해결할 수 있습니
이진 트리의 루트 노드가 주어졌을 때, 지그재그(ZigZag) 경로는 다음과 같이 정의됩니다.이진 트리에서 임의의 노드 하나와 방향(오른쪽 또는 왼쪽)을 선택합니다.현재 방향이 오른쪽이라면 현재 노드의 오른쪽 자식으로 이동하고, 그렇지 않다면 왼쪽 자식으로 이동합니다.이동 후에는 방향을 오른쪽에서 왼쪽으로, 또는 왼쪽에서 오른쪽으로 전환합니다.트리에서 더 이상 이동할 수 없을 때까지 두 번째와 세 번째 단계를 반복합니다.지그재그 경로의 길이는 방문한 노드 수에서 1을 뺀 값으로 정의됩니다. 즉, 노드가 하나만 있는 경우 길이는 0입
n개의 전구가 있는 방이 있다고 가정해 보겠습니다. 전구에는 1부터 n까지 번호가 붙어 있으며, 왼쪽에서 오른쪽으로 일렬로 배치되어 있습니다. 처음에는 모든 전구가 꺼져 있는 상태입니다. 순간 k(단, k는 0부터 n-1 사이의 값)마다 light[k] 번째 전구를 하나씩 켭니다. 어떤 전구는 자기 자신이 켜져 있고, 그 왼쪽에 있는 모든 전구들 역시 켜져 있을 때에만 파란색으로 바뀝니다. 우리가 구해야 하는 것은 켜져 있는 모든 전구가 파란색이 되는 순간의 개수입니다. 예를 들어 다음 그림과 같은 경우를 살펴보겠습니다 − 켜진
문제 개요n명의 직원이 있는 회사가 있다고 가정해 봅시다. 각 직원은 0부터 n-1까지의 고유한 ID를 가지며, 회사의 대표(CEO)는 headID에 해당하는 직원입니다. 각 직원은 한 명의 직속 상사를 가지며, manager 배열에서 manager[i]는 i번째 직원의 직속 상사를 의미합니다. 단, 대표자의 경우 manager[headID] = -1입니다. 또한 상하 관계는 항상 트리(tree) 형태의 구조를 이룬다는 것이 보장됩니다.대표는 회사의 긴급한 소식을 모든 직원에게 전달하려고 합니다. 대표가 먼저 자신의 직속 부하들에게
원본(original)과 복제본(cloned)이라는 두 개의 이진 트리가 있고, 원본 트리 내 특정 노드인 target에 대한 참조가 주어졌다고 가정해 봅시다. 복제된 트리는 원본 트리와 구조 및 값이 완전히 동일한 복사본입니다. 이때 우리가 해야 할 작업은 복제된 트리에서 원본의 target 노드와 동일한 위치에 있는 노드의 참조를 찾아 반환하는 것입니다.예를 들어 아래와 같은 트리에서 target이 값 3을 가진 노드라면, 출력 결과 역시 3이 됩니다.문제 해결 접근 방법두 트리의 구조가 완전히 동일하기 때문에, 원본 트리와 복
문제 개요 다음과 같은 연산을 지원하는 스택을 설계해 보겠습니다. CustomStack(int maxSize) — 스택에 저장할 수 있는 최대 원소 개수인 maxSize로 객체를 초기화합니다. 스택이 이미 maxSize에 도달했다면 더 이상 원소를 추가하지 않습니다. void push(int x) — 스택이 아직 maxSize에 도달하지 않았다면 x를 스택의 맨 위에 삽입합니다. int pop() — 스택의 맨 위 원소를 제거하고 그 값을 반환합니다. 스택이 비어 있으면 -1을 반환합니다. void inc(int k, int va
문제 개요이진 검색 트리(Binary Search Tree)가 주어졌을 때, 같은 노드 값들을 가지면서 균형이 잡힌 새로운 이진 검색 트리를 만들어야 합니다.여기서 균형 잡힌 트리란 모든 노드에 대해 왼쪽 서브트리와 오른쪽 서브트리의 깊이 차이가 1을 넘지 않는 경우를 의미합니다. 결과가 여러 개일 수 있다면 그중 아무거나 반환하면 됩니다.예를 들어 다음과 같은 트리가 입력으로 주어졌다고 가정해 보겠습니다.해결 접근 방법핵심 아이디어는 간단합니다. 이진 검색 트리를 중위 순회(Inorder Traversal)하면 항상 오름차순으로
정수 x의 거듭제곱 값(power)은 다음 규칙을 반복 적용하여 x를 1로 만들 때까지 필요한 단계 수로 정의됩니다.x가 짝수이면 x = x / 2x가 홀수이면 x = 3 * x + 1예를 들어 x = 3일 때의 거듭제곱 값은 7입니다. 3이 1이 되기까지 총 7단계가 필요하기 때문입니다(3 → 10 → 5 → 16 → 8 → 4 → 2 → 1).문제 설명정수 lo, hi, k가 주어졌을 때, 구간 [lo, hi]에 속한 모든 정수를 거듭제곱 값을 기준으로 오름차순 정렬해야 합니다. 이때 두 개 이상의 정수가 같은 거듭제곱 값을 가
문제 개요정수 배열 nums가 주어졌을 때, 배열 안에서 정확히 4개의 약수를 가진 정수들을 찾아 그 약수들의 합을 구하는 문제입니다. 만약 조건을 만족하는 정수가 하나도 없다면 0을 반환해야 합니다.예를 들어 입력이 [21, 4, 7]이라면 출력은 32입니다.21의 약수는 1, 3, 7, 21로 총 4개 → 약수의 합 = 324의 약수는 1, 2, 4로 총 3개 → 제외7의 약수는 1, 7로 총 2개 → 제외따라서 조건을 만족하는 유일한 숫자인 21의 약수 합인 32가 정답이 됩니다.접근 방법핵심 아이디어는 각 숫자에 대해 약수의
오름차순으로 정렬된 단일 연결 리스트(singly linked list)가 주어졌을 때, 이를 높이 균형 이진 검색 트리(height-balanced BST)로 변환하는 것이 목표입니다. 예를 들어 리스트가 [-10, -3, 0, 5, 9]와 같다면, 만들 수 있는 트리의 한 형태는 다음과 같습니다.해결 접근 방법핵심 아이디어는 정렬된 리스트의 가운데 원소를 루트로 삼는 것입니다. 가운데 값을 루트로 선택하면 그보다 작은 값들은 모두 왼쪽 절반에, 큰 값들은 모두 오른쪽 절반에 위치하게 되므로 BST의 성질이 자연스럽게 유지됩니다.
문제 개요여러 개의 단어로 구성된 문자열이 있다고 가정해 보겠습니다. 이때 문자열 안에서 단어들의 위치를 서로 반대로 뒤집어야 합니다. 예를 들어 입력 문자열이 The quick brown fox jumps over a lazy dog라면, 처리 결과는 dog lazy a over jumps fox brown quick The가 되어야 합니다.단순히 순서만 바꾸는 것 외에도, 실제 구현에서는 다음 조건들을 함께 처리해야 깔끔한 결과를 얻을 수 있습니다.문자열 맨 앞과 맨 뒤에 있는 공백은 모두 제거합니다.단어 사이에 공백이 여러 개
무한히 이어지는 정수 수열이 하나 있다고 가정해 봅시다. 이때 이 수열에서 n번째 자릿수가 무엇인지 찾아야 합니다. 예를 들어 입력이 11이라면 출력은 0입니다. 숫자들을 123456789101112처럼 차례대로 이어 붙였을 때 11번째 자리의 숫자가 0이기 때문입니다.문제 해결 접근 방법이 문제는 모든 숫자를 직접 나열하지 않고도 효율적으로 풀 수 있습니다. 핵심 아이디어는 한 자리 수(1~9), 두 자리 수(10~99), 세 자리 수(100~999)처럼 자릿수 구간별로 전체 자릿수 개수를 누적해 가면서, n번째 숫자가 어느 구간
문제 개요음이 아닌 정수 num이 문자열 형태로 주어져 있다고 가정해 보겠습니다. 이 숫자에서 k개의 자릿수를 제거했을 때, 남은 숫자가 가능한 한 가장 작은 값이 되도록 만들어야 합니다.예를 들어 입력이 1432219이고 k = 3이라면, 세 개의 자릿수를 적절히 제거한 결과는 1219가 됩니다.접근 방법: 스택을 이용한 탐욕 알고리즘이 문제는 스택(stack)과 탐욕(greedy) 기법을 조합하면 효율적으로 해결할 수 있습니다. 핵심 아이디어는 숫자를 왼쪽에서 오른쪽으로 하나씩 살펴보면서, 새로 등장한 숫자보다 큰 바로 앞자리
등차 수열이란 무엇인가?등차 수열(arithmetic sequence)은 최소 세 개 이상의 요소로 구성되며, 인접한 두 요소 사이의 차이가 항상 일정한 수열을 의미합니다. 예를 들어 [1, 3, 5, 7, 9], [7, 7, 7, 7], [3, -1, -5, -9]는 모두 등차 수열입니다. 반면 [1, 1, 2, 5, 7]은 요소 간 차이가 0, 1, 3, 2로 일정하지 않기 때문에 등차 수열이 아닙니다.문제 정의N개의 숫자로 이루어진 0-인덱스 배열 A가 주어졌다고 가정해 보겠습니다. 배열의 슬라이스(slice)는 0 <=