문제 개요2차원 이진 행렬이 하나의 직사각형 체스판을 나타낸다고 가정해 보겠습니다. 행렬에서 0은 빈 칸을 의미하고, 1은 나이트(knight)가 놓여 있는 칸을 의미합니다. 체스의 나이트는 가로로 두 칸, 세로로 한 칸 이동하거나, 반대로 세로로 두 칸, 가로로 한 칸 이동할 수 있습니다.이번 글에서 다룰 문제는 바로 체스판 위의 나이트들 중 서로 공격하고 있는 쌍이 존재하는지 판별하는 것입니다.예를 들어 입력이 다음과 같다면,000000100000010(1, 1) 위치의 나이트와 (2, 3) 위치의 나이트가 서로 공격 가능한 거
문제 정의숫자 리스트 nums와 정수 k가 주어졌을 때, nums[0] + nums[1] + ... + nums[i] ≤ k를 만족하는 최대 인덱스 i를 찾아야 합니다. 만약 조건을 만족하는 인덱스가 존재하지 않는다면 -1을 반환합니다.예시로 이해하기예를 들어 nums = [4, -7, 5, 2, 6], k = 5라고 가정해 보겠습니다. 이 경우 출력값은 3입니다.그 이유는 다음과 같습니다. 인덱스 3까지의 누적 합은 4 + (-7) + 5 + 2 = 4로 k보다 작거나 같습니다. 하지만 마지막 요소 6까지 더하면 합이 10이 되어
문제 이해하기숫자로 이루어진 리스트 nums가 주어졌을 때, 이 리스트를 먼저 정렬한 뒤 인접한 두 숫자 사이의 가장 큰 차이(간격)를 구하는 것이 목표입니다.예를 들어 입력이 [5, 2, 3, 9, 10, 11]이라면 출력은 4가 됩니다. 리스트를 정렬하면 [2, 3, 5, 9, 10, 11]이 되는데, 이때 5와 9 사이의 간격인 4가 가장 크기 때문입니다.해결 접근 방법이 문제는 다음 단계를 통해 해결할 수 있습니다.주어진 리스트 nums를 오름차순으로 정렬합니다.각 차이 값을 저장할 새로운 리스트를 준비합니다.정렬된 리스트를
숫자로 이루어진 리스트가 주어졌을 때, 가장 큰 수가 두 번째로 큰 수의 두 배보다 큰지 판별하는 문제를 살펴보겠습니다.예를 들어 리스트가 [3, 9, 6]이라면 최댓값은 9이고, 두 번째로 큰 값 6의 두 배는 12입니다. 9는 12보다 작으므로 결과는 False가 됩니다. 반면 리스트가 [6, 3, 15]라면 최댓값 15는 12보다 크므로 결과는 True가 됩니다.문제 접근 방법이 문제는 리스트를 한 번만 순회하면서 최댓값(c_max)과 두 번째로 큰 값(p_max)을 동시에 추적하면 선형 시간 O(n) 안에 해결할 수 있습니다
두 개의 값, 즉 숫자 num과 정수 k가 주어졌을 때, num의 자릿수 중 연속된 k개의 자릿수를 곱해 얻을 수 있는 가장 큰 값을 찾아야 합니다. 이때 num은 항상 k개 이상의 자릿수를 가진다고 가정합니다.예를 들어 입력이 num = 52689762, k = 4라면 출력은 3024가 됩니다. 연속된 4개의 자릿수 중 곱이 가장 큰 조합은 (8 × 9 × 7 × 6) = 3024이기 때문입니다.해결 접근 방법이 문제는 다음 단계를 따라 해결할 수 있습니다.최댓값을 저장할 변수 largest를 0으로 초기화합니다.num을 10^(
라틴 방진(Latin Square)은 각 행과 열에 서로 다른 숫자가 정확히 한 번씩만 나타나는 특수한 패턴을 가진 n×n 행렬입니다. 조합론, 통계학의 실험 설계, 스도쿠 퍼즐 등 다양한 분야에서 활용되는 개념입니다. 크기별 예시를 통해 패턴을 하나씩 살펴보겠습니다. 1 2 2 1 1 2 3 3 1 2 2 3 1 1 2 3 4 4 1 2 3 3 4 1 2 2 3 4 1 라틴 방진의 핵심 패턴 위 예시에서 확인할 수 있듯이, 라틴 방진은 입력값 n에 따라 다양한 크기로 생성됩니다. 행렬의 패턴을 자세히 관찰해 보면 한 가지 중요
문제 개요단일 연결 리스트(singly linked list)가 하나 주어졌다고 가정해 보겠습니다. 우리가 해야 할 작업은 이 연결 리스트의 길이, 즉 포함된 노드의 총 개수를 구하는 것입니다. 이 연결 리스트의 각 노드는 다음 노드를 가리키는 next 필드와 자기 자신의 값을 저장하는 val 필드를 가지고 있습니다.예를 들어 입력이 [2 -> 4 -> 5 -> 7 -> 8 -> 9 -> 3]과 같은 형태로 주어진다면, 노드가 총 7개이므로 결과값은 7이 됩니다.접근 방법연결 리스트의 길이를 구하는
BYOB(Build Your Own Botnet)는 보안 연구자와 개발자가 기본적인 봇넷을 직접 구축하고 운영해 볼 수 있는 오픈소스 프레임워크입니다. 매년 수백만 대의 기기를 감염시키고 현대적인 봇넷을 만들어내는 정교한 악성코드의 동작 원리를 깊이 이해함으로써, 이러한 위협에 대응하는 방어 기법을 개발하는 역량을 높이는 것이 핵심 목적입니다.RAT(Remote Administration Tool)나 C&C(Command & Control) 서버를 처음부터 직접 작성할 필요 없이, 개발자가 자신만의 코드를 손쉽게 구현하고 새
QR 코드는 제품 포장부터 항공권 탑승권에 이르기까지 자동으로 스캔해야 하는 거의 모든 분야에서 사용되는 기계 판독형 데이터 형식입니다. QR 코드가 일상 곳곳에 존재하기 때문에, 커스텀 QR 코드에 익스플로잇(취약점 공격 코드)을 담아 일반적인 취약점을 공격하는 것이 가능합니다. 실제로 해커들은 QRGen이라는 도구를 사용해 악성 QR 코드를 생성하고, 이를 통해 취약한 장치를 표적으로 삼습니다.QR 코드 공격이 강력한 이유는 사람이 스캔하지 않고서는 QR 코드에 담긴 정보를 읽거나 이해할 수 없기 때문입니다. 코드를 해독하려는
숫자 n이 주어졌을 때, n의 자릿수를 순환시켜 얻을 수 있는 모든 회전(rotations)이 소수인지 아닌지 확인해야 합니다.예를 들어 입력이 n = 13이라면 출력은 True가 됩니다. 13 자체가 소수이고, 자릿수를 회전한 31 역시 소수이기 때문입니다. 이처럼 모든 회전이 소수가 되는 수는 회전 소수(circular prime)라고도 불립니다.접근 방법이 문제는 다음 단계를 따라 해결할 수 있습니다.숫자 n을 문자열로 변환합니다.n의 길이만큼 반복하면서 다음을 수행합니다.현재 숫자가 소수가 아니라면 False를 반환합니다.그
문자열의 회전 그룹(rotation group)이란 해당 문자열이 가질 수 있는 모든 고유한 회전 형태를 모아 놓은 집합을 의미합니다. 예를 들어 입력이 567이라면, 이 문자열은 675와 756으로 회전할 수 있으며, 이 세 문자열은 모두 같은 회전 그룹에 속하게 됩니다.이제 문자열 목록 words가 주어졌을 때, 각 단어를 회전 그룹별로 묶고 총 그룹의 개수를 구하는 것이 목표입니다.예를 들어 입력이 다음과 같다면,words = [xyz, ab, ba, c, yzx]출력은 3이 됩니다. 회전 그룹이 정확히 세 개 존재하기 때문입
Python으로 런 길이 인코딩(RLE) 문자열을 원래 형태로 디코딩하는 방법문자열 s가 있다고 가정해 보겠습니다. s는 런 길이 인코딩(run-length encoding) 방식으로 압축된 문자열이며, 우리는 이를 다시 원래의 문자열로 복원(디코딩)해야 합니다.런 길이 인코딩(RLE)은 문자열을 빠르고 간단하게 압축하는 대표적인 기법입니다. 기본 아이디어는 연속해서 반복되는 문자들을 하나의 개수(count)와 문자(character) 쌍으로 표현하는 것입니다. 예를 들어 "BBBBAAADDCBB"라는 문자열은 &
런 길이 인코딩(Run-Length Encoding)이란? 문자열 s가 주어졌을 때, 이를 런 길이 인코딩(Run-Length Encoding) 기법으로 압축하는 방법을 살펴보겠습니다. 런 길이 인코딩은 문자열을 빠르고 간단하게 압축할 수 있는 대표적인 방법으로, 핵심 아이디어는 연속해서 반복되는 문자들을 개수 + 문자 형태로 하나씩 묶어 표현하는 것입니다. 예를 들어 입력 문자열이 s = BBBBAAADDCBB라면 출력 결과는 4B3A2D1C2B가 됩니다. 이는 B가 4번, A가 3번, D가 2번, C가 1번, 그리고 B가 다시
이진 문자열(binary string) s가 주어졌다고 가정해 봅시다. 우리는 서로 다른 두 개의 인접한 문자가 있을 때, 그 쌍을 삭제할 수 있습니다. 이 연산을 원하는 만큼 반복했을 때, 최종적으로 얻을 수 있는 가장 짧은 문자열의 길이를 구하는 것이 목표입니다.예를 들어 입력이 s = 1100011이라면 결과는 1이 됩니다.10을 삭제 → 10011다시 10을 삭제 → 01101을 삭제 → 1 남음접근 방법: 스택(Stack) 활용이 문제는 스택 자료구조를 사용하면 효율적으로 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니
문제 개요 숫자로 이루어진 리스트 nums가 주어졌을 때, 이 리스트의 연속된 부분 구간(서브리스트) 하나만 정렬하면 전체 배열이 오름차순으로 정렬되는 가장 짧은 구간의 길이를 구하는 문제입니다. 예를 들어 입력이 nums = [1, 2, 5, 4, 9, 10]이라면 출력은 2입니다. [5, 4] 구간만 정렬하면 [1, 2, 4, 5, 9, 10]이 되어 전체 리스트가 정렬되기 때문입니다. 해결 접근 방법 핵심 아이디어는 간단합니다. 원본 리스트를 정렬한 결과와 요소별로 비교했을 때, 처음으로 달라지는 위치부터 마지막으로 달라지는
문제 정의 문자열 s와 숫자 k가 주어집니다. 문자열의 각 문자는 점(.) 또는 x이며, 점은 비어 있는 공간을, x는 사람이 서 있는 자리를 의미합니다. 목표는 임의의 위치에 섰을 때 가장 가까운 사람과의 거리가 k 이상이 되도록 설 수 있는지 판별하는 것입니다. 이때 인접한 인덱스 사이의 거리는 1로 계산합니다. 예를 들어 s = x...x.., k = 2가 입력이라면 결과는 True입니다. 인덱스 2 또는 인덱스 6에 서면 가장 가까운 사람과의 거리가 정확히 2가 되어 조건을 만족하기 때문입니다. 해결 알고리즘 핵심 아이디어
숫자로 이루어진 리스트 nums가 주어졌을 때, 이 리스트를 정렬했을 경우 원래 자리 그대로 유지되는 요소가 몇 개인지 구하는 문제입니다.예를 들어 입력이 [2, 8, 4, 5, 11]이라면 결과는 2가 됩니다. 정렬된 리스트는 [2, 4, 5, 8, 11]이며, 이때 2와 11만 원래 위치와 동일하게 유지되기 때문입니다.해결 접근 방법이 문제는 다음과 같은 단계로 해결할 수 있습니다.리스트 nums를 정렬한 결과를 s에 저장합니다.카운터 변수 count를 0으로 초기화합니다.인덱스 0부터 리스트 길이까지 반복하면서 s[i]와 nu
이번 글에서는 여러 개의 사서함에 흩어져 있는 메일을 하나로 모으는 프로그램을 Python으로 구현해 보겠습니다. 각 사서함은 문자열 리스트로 표현되며, 문자열은 다음 세 가지 유형 중 하나입니다.J — 스팸 메일(Junk)P — 개인 메일(Personal)W — 업무 메일(Work)목표는 첫 번째 사서함부터 시작하여 라운드 로빈(round-robin) 방식으로 각 사서함을 순회하면서 스팸 메일(J)은 제거하고, 나머지 중요한 메일만 하나의 리스트로 합쳐 반환하는 것입니다.문제 예시입력이 다음과 같다고 가정해 보겠습니다.mailbo
숫자로 구성된 리스트 nums가 주어졌다고 가정해 봅시다. 이 리스트를 왼쪽과 오른쪽 양 끝에서 교차하듯 짜내어(압축하여) 마지막에는 단 하나의 요소만 남도록 만들어야 하며, 각 단계별 리스트의 상태를 모두 반환해야 합니다. 예를 들어 입력이 nums = [10, 20, 30, 40, 50, 60]이라면 결과는 다음과 같습니다. [[10, 20, 30, 40, 50, 60], [30, 30, 40, 110], [60, 150], [210]] 동작 원리 이해하기 첫 단계에서는
숫자로 이루어진 리스트가 주어졌을 때, 해당 리스트가 엄격하게 증가하는지 또는 엄격하게 감소하는지 확인해야 합니다. 여기서 엄격하게라는 것은 인접한 두 요소가 같은 값을 가질 수 없다는 의미입니다.예를 들어 입력이 nums = [10, 12, 23, 34, 55]라면 출력은 True가 됩니다. 모든 요소가 서로 다르고 각 요소가 바로 앞의 요소보다 크기 때문에, 이 리스트는 엄격하게 증가하는 리스트이기 때문입니다.문제 해결 접근 방법이 문제는 다음 단계를 통해 해결할 수 있습니다.nums의 길이가 2 이하라면 True를 반환합니다.