파이썬은 범용 프로그래밍 언어일 뿐만 아니라, 방대한 사용자 지원 모듈 생태계를 갖추고 있어 운영체제(OS) 수준의 프로그래밍에서도 탁월한 활용성을 보여줍니다. 이 글에서는 파이썬을 활용해 Windows 운영체제의 레지스트리(Registry)에 접근하는 방법을 단계별로 살펴보겠습니다. Windows 레지스트리에 접근하려면 파이썬 환경에 winreg 모듈을 임포트해야 합니다. winreg는 Windows 전용으로 제공되는 내장 모듈이므로 별도의 설치 과정 없이 바로 사용할 수 있습니다. 레지스트리 접근 기본 흐름 아래 예제에서는 wi
코딩 테스트에서 가장 자주 출제되는 대표적인 알고리즘 문제 중 하나인 Two Sum(두 수의 합)을 파이썬으로 해결하는 방법을 알아보겠습니다. 문제 설명 정수로 이루어진 배열이 하나 주어집니다. 이 배열에서 두 요소를 골라 더했을 때 주어진 목표값(target)과 일치하도록 만드는 두 요소의 인덱스를 반환해야 합니다. 여기에는 한 가지 전제 조건이 있습니다. 바로 항상 유일한 해가 하나만 존재한다는 것입니다. 즉, 동일한 목표값에 대해 두 개 이상의 서로 다른 인덱스 쌍이 존재하는 경우는 없다고 가정합니다. 예시 배열이 A = [2
32비트 부호 있는(signed) 정수가 하나 주어졌다고 가정해 보겠습니다. 이 숫자의 자릿수를 거꾸로 뒤집어야 합니다. 예를 들어 숫자가 425라면 출력은 524가 됩니다. 숫자에는 부호가 붙을 수 있으므로 음수도 함께 처리해야 합니다. 따라서 입력이 -425라면 출력은 -524가 되어야 합니다. 문제의 전제 조건 이 문제에서는 값이 32비트 부호 있는 정수 범위 안에 있다고 가정합니다. 유효한 범위는 [-231, 231 − 1], 즉 [-2147483648, 2147483647]입니다. 뒤집은 결과가 이 범위를 벗어나 오버플로우
정수가 주어졌을 때, 그 숫자가 회문(Palindrome)인지 판별해야 하는 경우가 있습니다. 회문이란 앞에서 읽으나 뒤에서 읽으나 같은 숫자를 의미합니다.예를 들어 454라는 숫자가 있다고 가정해 보겠습니다. 이 숫자를 뒤집어도 여전히 454이므로 회문입니다. 반면 -565를 뒤집으면 565-가 되어 원래 값과 다르기 때문에 회문이 아닙니다. 즉, 음수는 항상 회문이 될 수 없습니다.해결 접근 방식이 문제를 해결하는 가장 간단한 방법은 다음과 같습니다.정수를 문자열로 변환합니다.슬라이싱을 이용해 문자열을 뒤집습니다.원래 문자열과
로마자 표기된 문자열이 주어졌을 때, 이를 정수로 변환하는 문제를 살펴보겠습니다. 로마 숫자는 아래와 같은 기호들로 표현됩니다.기호값I1V5X10L50C100D500M1000로마 숫자의 규칙로마 숫자의 구조를 자세히 보면 그 규칙을 이해할 수 있습니다. 예를 들어 II는 I 두 개가 더해진 값이므로 2입니다. XII는 X + II = 10 + 2 = 12가 됩니다.하지만 주의할 점이 있습니다. 4는 IIII가 아니라 IV로 표기됩니다. 이것이 바로 로마 숫자에서 까다로운 부분입니다.I는 V(5)나 X(10) 앞에 위치하여 각각 4와
배열에 여러 개의 문자열이 저장되어 있다고 가정해 봅시다. 우리가 해야 할 일은 이 문자열들 사이에서 가장 긴 공통 접두사(Longest Common Prefix)를 찾는 것입니다. 이번 문제에서는 모든 문자열이 소문자로만 이루어져 있다고 가정하며, 만약 공통 접두사가 하나도 존재하지 않는다면 빈 문자열("")을 반환하면 됩니다.예를 들어 문자열 배열이 ["school", "schedule", "scotland"]과 같이 주어졌다면, 세 문자열 모두 앞부분에 &
정렬된 두 개의 리스트 A와 B가 있다고 가정해 보겠습니다. 이 두 리스트를 병합하여 하나의 정렬된 리스트 C를 만들어야 하며, 두 리스트의 크기는 서로 다를 수 있습니다.예를 들어, A = [1,2,4,7]이고 B = [1,3,4,5,6,8]이라면, 병합된 리스트 C는 [1,1,2,3,4,4,5,6,7,8]이 됩니다.재귀를 활용한 병합 접근법이 문제는 재귀(recursion)를 사용하여 해결할 수 있습니다. merge() 함수는 다음과 같은 방식으로 동작합니다.merge() 함수에 리스트 A와 B를 전달합니다.A가 비어 있으면 B
정렬된 리스트 A가 주어졌을 때, 모든 중복 항목을 제거한 뒤 배열의 길이를 반환해야 합니다. 이 문제에는 추가 공간을 O(1)만 사용할 수 있다는 제약 조건이 있으므로, 연산은 반드시 제자리(in-place) 방식으로 수행해야 합니다.예를 들어 A = [1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6]라면, 고유한 원소는 1, 2, 3, 4, 5, 6으로 총 6개이므로 출력 결과는 6이 됩니다.해결 알고리즘배열이 이미 정렬되어 있다는 점이 핵심 힌트입니다. 정렬된 상태에서는 중복된 값들이 항상 서로 인접해
문제 정의두 개의 문자열 haystack(전체 문자열)과 needle(찾고자 하는 부분 문자열)이 주어졌을 때, needle이 haystack 안에서 처음 나타나는 인덱스를 찾아야 합니다.예를 들어, 전체 문자열이 "helloworld"이고 찾으려는 부분 문자열이 "lo"라면, 결과는 3이 됩니다. 이는 "lo"가 인덱스 3부터 시작하기 때문입니다.C 언어에는 이러한 기능을 수행하는 표준 라이브러리 함수인 strstr()이 존재하지만, 여기서는 이와 동일하게 동작하는 함수를 직접
Count and Say 수열이란?Count and Say(세고 말하기) 수열은 이전 항을 소리 내어 읽는 방식으로 다음 항을 만들어 가는 흥미로운 수열입니다. 처음 몇 개의 항은 다음과 같습니다.111211211111221수열을 읽는 규칙각 항은 바로 앞 항을 읽으면서 연속된 숫자의 개수와 그 숫자 자체를 차례로 말하는 방식으로 생성됩니다.1 → "1" (하나의 1)11 → 이전 항 "1"을 읽어 "1이 하나"라고 말합니다.21 → 이전 항 "
정수 배열 A가 주어졌을 때, 길이가 1 이상인 연속된 부분 배열(contiguous subarray) 중에서 원소의 합이 가장 큰 구간을 찾고, 그 합을 반환하는 문제입니다.예를 들어 배열이 A = [-2, 1, -3, 4, -1, 2, 1, -5, 4]라고 한다면, 합이 가장 큰 부분 배열은 [4, -1, 2, 1]이며 그 합은 6입니다.동적 계획법(Dynamic Programming) 접근 방식이 문제는 동적 계획법을 활용하면 효율적으로 해결할 수 있습니다. 핵심 아이디어는 다음과 같습니다.배열 A와 같은 크기의 dp 배열을
문제 개요정수 배열 A가 있다고 가정해 보겠습니다. 배열 A는 n개의 음수가 아닌 원소를 담고 있으며, 배열 전체가 하나의 큰 숫자를 나타냅니다. 예를 들어 A = [5, 3, 2, 4]가 주어지면 이는 숫자 5324를 의미합니다.우리가 해야 할 일은 배열 A가 나타내는 숫자에 1을 더한 뒤, 그 결과를 다시 배열 형태로 반환하는 것입니다. 따라서 위의 예에서 1을 더하면 A는 [5, 3, 2, 5]가 됩니다.해결 접근 방법이 문제는 다음과 같은 단계로 해결할 수 있습니다.배열의 각 자릿수를 문자열에 차례대로 이어 붙여 하나의 문자
음이 아닌 정수 x가 주어졌을 때, 라이브러리 함수를 사용하지 않고 x의 제곱근을 구하는 문제입니다. 즉, 직접 함수를 작성해 sqrt(x)를 계산해야 하며, 결과의 소수점 이하는 버리고 정수 부분만 반환합니다.예를 들어 x가 4라면 결과는 2입니다. x가 8인 경우에도 결과는 2인데, 실제 sqrt(8)은 약 2.82842이지만 여기서는 정수 부분만 취하기 때문입니다.풀이 접근 방식이 문제는 이진 탐색(Binary Search)을 활용하면 효율적으로 해결할 수 있습니다. 탐색 범위를 절반씩 좁혀가면서, 제곱했을 때 x보다 작거나
정렬된 두 개의 배열 A와 B가 있다고 가정해 봅시다. 이 두 배열을 병합하여 하나의 정렬된 배열 C를 만들어야 하며, 두 배열의 크기는 서로 달라도 됩니다.예를 들어, A = [1,2,4,7]이고 B = [1,3,4,5,6,8]이라면, 병합된 배열 C는 [1,1,2,3,4,4,5,6,7,8]이 됩니다.알고리즘 접근 방법이 문제는 다음 단계를 따라 해결할 수 있습니다.i := 0, j := 0으로 초기화하고, end := A의 길이 − 1로 설정합니다.end ≥ 0이면서 A[end]가 비어 있는(0인) 동안 end 값을 1씩 감소시
대칭 이진 트리란?하나의 이진 트리가 주어졌을 때, 해당 트리가 대칭(symmetric) 트리인지 판별해야 합니다. 트리를 좌우로 뒤집은 거울상(미러 이미지)이 원래 트리와 완전히 동일할 때, 그 트리를 대칭 트리라고 부릅니다.예를 들어 아래 두 트리 중 첫 번째 트리는 대칭이지만, 두 번째 트리는 일부 노드의 위치가 어긋나 있어 대칭이 아닙니다.해결 접근 방법대칭 여부는 루트의 왼쪽 서브트리와 오른쪽 서브트리를 서로 미러링하며 비교하는 재귀 방식으로 해결할 수 있습니다. 구체적인 단계는 다음과 같습니다.solve(root, roo
이진 트리(Binary Tree)가 하나 주어졌을 때, 해당 트리의 최대 깊이(Maximum Depth)를 구하는 것이 이번 글의 목표입니다. 여기서 최대 깊이란 루트(Root) 노드에서 출발하여 가장 긴 경로를 따라 리프(Leaf) 노드에 도달할 때까지 거치는 노드 수의 최댓값을 의미합니다.예를 들어 위 그림과 같은 트리가 있다면, 루트에서 리프까지 가장 긴 경로가 지나는 노드는 총 3개이므로 최대 깊이는 3이 됩니다.해결 접근 방법이 문제는 재귀(Recursion)를 활용하면 매우 간단하게 해결할 수 있습니다. 핵심 아이디어는
문제 개요정렬된 배열 A가 하나 주어져 있을 때, 이를 높이 균형(height-balanced) 이진 탐색 트리로 변환해야 합니다. 여기서 높이 균형 이진 트리란, 모든 노드에 대해 왼쪽 하위 트리와 오른쪽 하위 트리의 깊이 차이가 절대 1을 초과하지 않는 이진 트리를 의미합니다.예를 들어 배열이 [-10, -3, 0, 5, 9]라고 한다면, 가능한 출력 결과 중 하나는 다음과 같은 형태입니다: [0, -3, 9, -10, null, 5]해결 접근 방법이 문제는 다음 단계를 따라 해결할 수 있습니다.배열 A가 비어 있다면 None을
문제 개요하나의 이진 트리와 목표 합(sum)이 주어졌다고 가정해 보겠습니다. 우리가 찾아야 하는 것은 루트 노드에서 시작하여 리프 노드까지 따라 내려가는 경로 중, 경로상 노드 값들의 합이 주어진 값과 정확히 일치하는 경로입니다.예를 들어 트리가 [0, -3, 9, -10, null, 5]이고 목표 합이 14라고 한다면, 0 → 9 → 5 경로를 따라가면 0 + 9 + 5 = 14가 되므로 조건을 만족하는 경로가 존재합니다.해결 접근 방법이 문제는 재귀(DFS) 방식으로 깔끔하게 해결할 수 있습니다. 핵심 아이디어는 루트에서 리프
배열 A가 주어졌다고 가정해 봅시다. 여기서 A[i]는 i번째 날의 특정 주식 가격을 나타냅니다. 우리의 목표는 딱 한 번의 거래(주식을 사고 파는 행위)로 얻을 수 있는 최대 이익을 구하는 것입니다. 단, 동시에 여러 건의 거래를 진행할 수 없으므로 새로운 주식을 사기 전에 반드시 기존에 보유한 주식을 먼저 팔아야 합니다.예를 들어 배열이 A = [7, 1, 5, 3, 6, 4]라고 해보겠습니다. 이 경우 결과값은 5가 됩니다. 2일째(인덱스 1)에 가격 1로 주식을 사고, 5일째에 가격 6으로 팔면 이익이 6 − 1 = 5가 되
문제 개요배열 A가 주어졌을 때, A[i]는 i번째 날의 특정 주식 가격을 나타냅니다. 우리는 가능한 한 많은 거래(매수와 매도)를 반복하여 얻을 수 있는 최대 이익(maximum profit)을 구해야 합니다.단, 한 가지 중요한 제약 조건이 있습니다. 동시에 여러 건의 거래에 참여할 수 없다는 점입니다. 즉, 새 주식을 구매하기 전에 반드시 기존에 보유한 주식을 먼저 팔아야 합니다.예제배열이 다음과 같다고 가정해 보겠습니다.A = [7, 1, 5, 3, 6, 4]이 경우 결과값은 7입니다. 그 이유를 살펴보면 다음과 같습니다.2