코딩 테스트 면접을 준비하며 자료구조와 빈출 주제 위주로 정리하였습니다.
def is_palindrome(word):
left = 0
right = len(word)-1
while left < right:
if word[left] != word[right]:
return False
left, right = left + 1, right - 1
return True
def find_max_min(arr):
max_value = arr[0]
min_value = arr[0]
for i in range(1, len(arr)):
if arr[i] > max_value:
max_value = arr[i]
if arr[i] < min_value:
min_value = arr[i]
return max_value, min_value
def find_max_two(arr):
if len(arr) < 2:
return arr
max1, max2 = arr[:2]
if max2 > max1:
max1, max2 = max2, max1
for n in arr[2:]:
if n > max1:
max1, max2 = n, max1
elif n > max2:
max2 = n
return [max1, max2]
def reverse_array(arr):
left = 0
right = len(arr) - 1
while left < right:
arr[left], arr[right] = arr[right], arr[left]
left += 1
right -= 1
return arr
target
이 되는 두 숫자의 인덱스 찾기def twoSum(nums, target):
# 숫자와 숫자의 원래 인덱스를 저장하는 2차원 배열을 생성한다.
nums = [[n, i] for i, n in enumerate(nums)]
# 배열을 숫자의 오름차순으로 정렬한다.
nums.sort(key=lambda x: x[0])
# 첫 번째 인덱스와 마지막 인덱스를 각각 가리키는 두 포인터를 생성한다.
l, r = 0, len(nums) - 1
# 왼쪽 포인터가 오른쪽 포인터보다 작을 동안 반복한다.
while l < r:
num_sum = nums[l][0] + nums[r][0]
# 만약 두 포인터가 가리키는 숫자의 합이 target과 같으면 결과 출력한다.
if num_sum == target:
return [nums[l][1], nums[r][1]]
# 합이 target보다 크면 오른쪽 포인터를 왼쪽으로 한칸 옮긴다.
elif num_sum > target:
r -= 1
# 합이 target보다 작으면 왼쪽 포인터를 오른쪽으로 한칸 옮긴다.
else:
l += 1
def bin_array_sort(arr):
left = 0
right = len(arr) - 1
while left < right:
while left < len(arr) and arr[left] == 0:
left += 1
while right >= 0 and arr[right] == 1:
right -= 1
if left < right:
arr[left], arr[right] = 0, 1
left, right = left + 1, right - 1
def are_anagrams(str1, str2):
# 길이가 다르면 애너그램이 될 수 없음
if len(str1) != len(str2):
return False
# 두 문자열을 정렬하여 비교
return sorted(str1) == sorted(str2)
def are_anagrams(str1, str2):
# 길이가 다르면 애너그램이 될 수 없음
if len(str1) != len(str2):
return False
# 두 문자열의 각 문자의 빈도를 저장할 딕셔너리
count1 = {}
count2 = {}
# str1의 각 문자의 빈도 계산
for char in str1:
if char in count1:
count1[char] += 1
else:
count1[char] = 1
# str2의 각 문자의 빈도 계산
for char in str2:
if char in count2:
count2[char] += 1
else:
count2[char] = 1
# 두 빈도 딕셔너리를 비교
return count1 == count2
def has_unique_chars(s):
sorted_s = sorted(s)
for i in range(1, len(sorted_s)):
if sorted_s[i] == sorted_s[i - 1]:
return False
return True
def has_unique_chars(s):
char_set = {}
for char in s:
if char in char_set:
return False
char_set[char] = True
return True
def reverse_string(s):
reversed_s = ""
for char in s:
reversed_s = char + reversed_s
return reversed_s
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
class SinglyLinkedList:
def __init__(self):
# 연결 리스트의 머리(head) 노드
self.head = None
# 리스트의 끝에 새 노드를 추가
def append(self, data):
# 새 노드를 생성
new_node = Node(data)
# 리스트가 비어있으면 새 노드를 머리로 설정
if self.head is None:
self.head = new_node
return
# 리스트의 마지막 노드를 찾음
last_node = self.head
while last_node.next:
last_node = last_node.next
# 마지막 노드의 다음을 새 노드로 설정
last_node.next = new_node
# 리스트의 머리에 새 노드를 추가
def prepend(self, data):
# 새 노드를 생성
new_node = Node(data)
# 새 노드의 다음을 현재 머리로 설정
new_node.next = self.head
# 머리를 새 노드로 업데이트
self.head = new_node
# 주어진 키를 가진 첫 번째 노드를 삭제
def delete_node(self, key):
# 현재 노드를 머리로 설정
current_node = self.head
# 삭제할 노드가 머리에 있는 경우
if current_node and current_node.data == key:
self.head = current_node.next
current_node = None
return
# 삭제할 노드를 찾음
previous_node = None
while current_node and current_node.data != key:
previous_node = current_node
current_node = current_node.next
# 삭제할 노드를 찾지 못한 경우
if current_node is None:
return
# 이전 노드의 다음을 삭제할 노드의 다음으로 설정
previous_node.next = current_node.next
current_node = None
# 주어진 키를 가진 노드를 검색
def search(self, key):
# 현재 노드를 머리로 설정
current_node = self.head
# 노드를 순회하며 키를 찾음
while current_node and current_node.data != key:
current_node = current_node.next
# 키를 찾으면 True, 아니면 False 반환
return current_node is not None
# 리스트의 모든 노드를 순회하며 데이터 값을 출력
def print_list(self):
# 현재 노드를 머리로 설정
current_node = self.head
# 노드를 순회하며 데이터 값을 출력
while current_node:
print(current_node.data, end=" -> ")
current_node = current_node.next
print("None")
class Stack:
def __init__(self):
# 내부 리스트를 사용하여 스택 요소를 저장
self.stack = []
def push(self, item):
# 스택의 맨 위에 요소를 추가
self.stack.append(item)
def pop(self):
# 스택이 비어있는 경우 예외 처리
if self.is_empty():
raise IndexError("pop from empty stack")
# 스택의 맨 위 요소를 제거하고 반환
return self.stack.pop()
def peek(self):
# 스택이 비어있는 경우 예외 처리
if self.is_empty():
raise IndexError("peek from empty stack")
# 스택의 맨 위 요소를 반환 (제거하지 않음)
return self.stack[-1]
def is_empty(self):
# 스택이 비어있는지 여부를 반환
return len(self.stack) == 0
def size(self):
# 스택의 요소 개수를 반환
return len(self.stack)
def print_stack(self):
# 스택의 모든 요소를 출력
print(self.stack)
def reverse_word(word: str) -> str:
answer: str = ""
s = Stack()
for w in word:
s.push(w)
while not s.is_empty():
answer += s.pop()
return answer
def check_bracket(expression):
s = Stack()
for exp in expression:
if exp == "(":
s.push(exp)
elif exp == ")":
if not s.pop():
return False
return True if s.is_empty() else False
def find_nge(arr)]:
n = len(arr)
stack = []
res = [-1] * n
for i in range(n-1, -1, -1):
while stack:
if stack[-1] > arr[i]: # 스택의 맨 위 요소가 현재 요소보다 큰 경우 NGE
res[i] = stack[-1]
break
else:
stack.pop()
stack.append(arr[i])
return res
class Queue:
def __init__(self):
# 내부 리스트를 사용하여 큐 요소를 저장
self.queue = []
def enqueue(self, item):
# 큐의 끝에 요소를 추가
self.queue.append(item)
def dequeue(self):
# 큐가 비어있는 경우 예외 처리
if self.is_empty():
raise IndexError("dequeue from empty queue")
# 큐의 맨 앞 요소를 제거하고 반환
return self.queue.pop(0)
def front(self):
# 큐가 비어있는 경우 예외 처리
if self.is_empty():
raise IndexError("front from empty queue")
# 큐의 맨 앞 요소를 반환 (제거하지 않음)
return self.queue[0]
def is_empty(self):
# 큐가 비어있는지 여부를 반환
return len(self.queue) == 0
def size(self):
# 큐의 요소 개수를 반환
return len(self.queue)
def print_queue(self):
# 큐의 모든 요소를 출력
print(self.queue)
def josephus_q(n, k):
res = []
q = Queue()
# 큐에 사람들을 추가 (1부터 n까지)
for i in range(n):
q.enqueue(i + 1)
# Josephus 문제 해결
while q.size() > 1:
# k-1번 dequeued된 요소를 다시 enqueue하여 순환시킴
for _ in range(k - 1):
q.enqueue(q.dequeue())
# k번째 사람을 큐에서 제거하고 결과 리스트에 추가
res.append(q.dequeue())
# 마지막 남은 사람을 결과 리스트에 추가
res.append(q.dequeue())
return res
def generate_binary_numbers(n):
result = []
q = Queue()
# 큐에 첫 번째 이진수 "1" 추가
q.enqueue("1")
# n번 반복
for _ in range(n):
# 큐에서 요소 꺼내기
current = q.dequeue()
result.append(current)
# 새로운 이진수 생성하여 큐에 추가
q.enqueue(current + "0")
q.enqueue(current + "1")
return result
queue의 enqueue()를 구현할 때 첫 번째 stack을 사용하고, dequeue()를 구현할 때 두 번째 stack을 사용하면 queue를 구현할 수 있다.
구현 방법
enqueue()에 사용할 stack을 instack이라고 부르고 dequeue()에 사용할 stack을 outstack이라고 하자.
두 개의 stack으로 queue를 구현하는 방법은 다음과 같다.
시간 복잡도
class Queue(object):
def __init__(self):
self.instack=[]
self.outstack=[]
def enqueue(self,element):
self.instack.append(element)
def dequeue(self):
if not self.outstack:
while self.instack:
self.outstack.append(self.instack.pop())
return self.outstack.pop()
구현 방법
push()에 사용할 queue는 q1이라고 부르고 pop()에 사용할 queue를 q2라고 하자.
두 개의 queue로 stack을 구현하는 방법은 다음과 같다.
시간 복잡도
import queue
class Stack(object):
def __init__(self):
self.q1 = queue.Queue()
self.q2 = queue.Queue()
def push(self, element):
self.q1.put(element)
def pop(self):
while self.q1.qsize() > 1:
self.q2.put(self.q1.get())
temp = self.q1
self.q1 = self.q2
self.q2 = temp
return self.q2.get()
class CircularQueue:
def __init__(self, capacity):
# 큐의 최대 용량을 설정
self.capacity = capacity
# 큐의 요소를 저장할 리스트를 초기화, 초기에는 None으로 채움
self.queue = [None] * capacity
# 큐의 첫 번째 요소를 가리키는 인덱스
self.front = -1
# 큐의 마지막 요소를 가리키는 인덱스
self.rear = -1
def is_full(self):
# 큐가 가득 찼는지 확인
# rear의 다음 위치가 front와 같다면 큐가 가득 찬 상태
return (self.rear + 1) % self.capacity == self.front
def is_empty(self):
# 큐가 비어있는지 확인
# front가 -1이면 큐는 비어 있음
return self.front == -1
def enqueue(self, item):
# 큐에 요소를 추가
if self.is_full():
raise OverflowError("Circular Queue is full")
if self.is_empty():
# 큐가 비어있으면 front를 0으로 설정
self.front = 0
# rear를 순환하여 다음 위치를 가리키게 함
self.rear = (self.rear + 1) % self.capacity
# 큐의 rear 위치에 새로운 요소를 추가
self.queue[self.rear] = item
def dequeue(self):
# 큐에서 요소를 제거하고 반환
if self.is_empty():
raise IndexError("Circular Queue is empty")
# front 위치의 요소를 임시 저장
item = self.queue[self.front]
# 큐에 요소가 하나만 있는 경우
if self.front == self.rear:
# 큐를 비우므로 front와 rear를 초기 상태로 설정
self.front = -1
self.rear = -1
else:
# front를 순환하여 다음 위치를 가리키게 함
self.front = (self.front + 1) % self.capacity
return item
def peek(self):
# 큐의 맨 앞 요소를 제거하지 않고 반환
if self.is_empty():
raise IndexError("Circular Queue is empty")
return self.queue[self.front]
def print_queue(self):
# 큐의 모든 요소를 출력
if self.is_empty():
print("Circular Queue is empty")
return
if self.rear >= self.front:
# rear가 front보다 크거나 같은 경우
# front부터 rear까지의 요소를 출력
print("Queue:", self.queue[self.front:self.rear + 1])
else:
# rear가 front보다 작은 경우 (순환이 발생한 경우)
# front부터 끝까지와 시작부터 rear까지의 요소를 출력
print("Queue:", self.queue[self.front:] + self.queue[:self.rear + 1])
class HashTable:
def __init__(self, length=5):
self.max_len = length
self.table = [[] for _ in range(self.max_len)]
def _hash(self, key):
# 키의 각 문자의 아스키 값을 더하고 테이블 크기로 나눈 나머지를 해시 값으로 사용
res = sum([ord(s) for s in key])
return res % self.max_len
def set(self, key, value):
# 키에 대한 해시 값을 계산하여 인덱스를 얻음
index = self._hash(key)
# 해당 인덱스의 리스트에 키-값 쌍을 추가
self.table[index].append((key, value))
def get(self, key):
# 키에 대한 해시 값을 계산하여 인덱스를 얻음
index = self._hash(key)
# 해당 인덱스의 리스트를 검색하여 키가 일치하는 값을 찾음
value = self.table[index]
if not value:
return None
for v in value:
if v[0] == key:
return v[1]
return None
def find_duplicates(arr):
# 해시 테이블 역할을 하는 딕셔너리
hash_table = {}
# 중복된 값을 저장할 리스트
duplicates = []
# 배열의 각 요소를 순회
for value in arr:
# 값이 해시 테이블에 이미 존재하는지 확인
if value in hash_table:
# 중복된 값이 이미 저장되어 있는지 확인 후 추가
if value not in duplicates:
duplicates.append(value)
else:
# 해시 테이블에 값을 추가
hash_table[value] = True
return duplicates
def maxLen_dic(arr):
dic = {0: -1} # 초기 딕셔너리
ans = 0 # 최대 길이 초기화
total = 0 # 부분 누적 합 초기화
for i in range(len(arr)):
total += arr[i] # 현재 인덱스까지의 누적 합 계산
if total in dic:
# 현재 인덱스와 누적 합이 처음 등장한 인덱스 사이의 부분 배열 길이 계산
ans = max(ans, i - dic[total])
else:
# 누적 합이 처음 등장했으므로 인덱스를 딕셔너리에 추가
dic[total] = i
return ans # 최대 길이 반환
def levelorder(tree):
if not tree:
return []
res, queue = [], [0]
while queue:
index = queue.pop(0)
res.append(tree[index])
index = 2 * index + 1
if index < len(tree) and tree[index] is not None:
queue.append(index)
index += 1
if index < len(tree) and tree[index] is not None:
queue.append(index)
return res
from collections import deque
def levelorder(root):
visited = []
if root is None:
return 0
q = deque()
q.append(root)
while q:
cur_node = q.popleft()
visited.append(cur_node.value)
if cur_node.left:
q.append(cur_node.left)
if cur_node.right:
q.append(cur_node.right)
return visited
def preorder(root):
if root is None:
return
print(root)
preorder(root.left)
preorder(root.right)
def preorder(tree):
if not tree:
return []
res, stack = [], [0]
while stack:
index = stack.pop()
res.append(tree[index])
index = 2 * index + 2
if index < len(tree) and tree[index] is not None:
stack.append(index)
index -= 1
if index < len(tree) and tree[index] is not None:
stack.append(index)
return res
def inorder(root):
if root is None:
return
inorder(root.left)
print(root)
inorder(root.right)
def inorder(tree):
if not tree:
return []
index = 0
res, stack = [], []
while True:
if index < len(tree) and tree[index] is not None:
stack.append(index)
index = 2 * index + 1
elif stack:
index = stack.pop()
res.append(tree[index])
index = 2 * index + 2
else:
break
return res
def postorder(root):
if root is None:
return
postorder(root.left)
postorder(root.right)
print(root)
def postorder(tree):
if not tree:
return []
res, stack = [], [0]
visit_order = []
while stack:
index = stack.pop()
visit_order.append(index)
index = 2 * index + 1
if index < len(tree) and tree[index] is not None:
stack.append(index)
index = index + 1
if index < len(tree) and tree[index] is not None:
stack.append(index)
while visit_order:
index = visit_order.pop()
res.append(tree[index])
return res
def heappush(heap, data):
heap.append(data)
# 추가한 원소의 인덱스를 구한다.
current = len(heap) - 1
# 현재 원소가 루트(인덱스 0)에 도달하면 종료
while current > 0:
# 추가한 원소의 부모 인덱스를 구한다.
parent = (current - 1) // 2
# 새 값이 부모의 값보다 작으면 값을 교환
if heap[parent] > heap[current]:
heap[parent], heap[current] = heap[current], heap[parent]
# 추가한 원소의 인덱스를 갱신한다.
current = parent
else:
break
def heappop(heap):
if not heap:
return "Empty Heap!"
elif len(heap) == 1:
return heap.pop()
pop_data, heap[0] = heap[0], heap.pop()
current, child = 0, 1
while child < len(heap):
sibling = child + 1
if sibling < len(heap) and heap[child] > heap[sibling]:
child = sibling
if heap[current] > heap[child]:
heap[current], heap[child] = heap[child], heap[current]
current = child
child = current * 2 + 1
else:
break
return pop_data
def heapify(arr):
last = len(arr) // 2 - 1
for current in range(last, -1, -1):
while current <= last:
child = current * 2 + 1
sibling = child + 1
if sibling < len(arr) and arr[child] > arr[sibling]:
child = sibling
if arr[current] > arr[child]:
arr[current], arr[child] = arr[child], arr[current]
current = child
else:
break
visited = []
def dfs(cur_v):
visited.append(cur_v)
for v in graph[cur_v]:
if v not in visited:
dfs(v)
def dfs(graph, node):
# 방문할 노드를 저장한 스택과 방문 여부를 확인한 집합을 만든다.
# 스택과 집합에 방문할 첫 노드를 넣는다.
res = []
stack = [node]
visited = set(stack)
# 스택이 빌 때까지 반복한다.
while stack:
# 스택에서 노드를 꺼내고 방문처리한다.
u = stack.pop()
res.append(u)
# 현재 노드에 연결된 다른 노드를 확인한다.
# 다른 노드가 아직 방문하지 앟는 노드이면, 스택과 집합에 넣는다.
for v in graph[u]:
if v not in visited:
visited.add(v)
stack.append(v)
return res
from collections import deque
def bfs(graph, start_v):
visited = [start_v]
queue = deque(start_v)
while queue:
cur_v = queue.popleft()
for v in graph[cur_v]:
if v not in visited:
visited.append(v)
queue.append(v)
return visited
def bubble_sort(arr):
n = len(arr)
# 반복문을 돌면서 인접한 두 원소를 비교
for i in range(n-1):
for j in range(n-i-1):
# 현재 원소가 다음 원소보다 크면 두 원소의 위치를 바꿈
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr
def selection_sort(arr):
for i in range(len(arr)):
min_index = i
for j in range(i+1, len(arr)):
if arr[j] < arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
def insertion_sort(arr):
for i in range(1, len(arr)):
j = i
while j > 0 and arr[j] < arr[j-1]:
arr[j], arr[j-1] = arr[j-1], arr[j]
j -= 1
return arr
def quicksort(arr):
# 배열의 크기가 1 이하이면 정렬할 필요가 없으므로 해당 배열을 반환한다.
if len(arr) <= 1:
return arr
# 배열의 가운데 값을 pivot으로 지정한다.
pivot = arr[len(arr) // 2]
# pivot을 기준으로 작은 값은 left 배열, 큰 값은 right 배열, 같은 값은 equal 배열에 담는다.
left = []
right = []
equal = []
for num in arr:
if num < pivot:
left.append(num)
elif num > pivot:
right.append(num)
else:
equal.append(num)
# left, equal, right 배열을 각각 재귀적으로 정렬한 후 합쳐서 반환한다.
return quicksort(left) + equal + quicksort(right)
def quick_select(arr, left, right, k):
# 배열의 left에서 right까지 부분에서 k번째 큰 수를 찾는 함수
if left <= right:
pivot_index = partition(arr, left, right)
if pivot_index == k:
# 피벗 인덱스가 k와 같으면 피벗 위치의 값이 k번째 큰 수
return arr[pivot_index]
elif pivot_index < k:
# 피벗 인덱스가 k보다 작으면 오른쪽 부분 배열에서 탐색
return quick_select(arr, pivot_index + 1, right, k)
else:
# 피벗 인덱스가 k보다 크면 왼쪽 부분 배열에서 탐색
return quick_select(arr, left, pivot_index - 1, k)
def partition(arr, left, right):
# 배열을 피벗을 기준으로 나누는 함수
pivot = arr[right]
i = left - 1
for j in range(left, right):
if arr[j] >= pivot: # 내림차순으로 정렬하기 위해 `>=` 사용
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[right] = arr[right], arr[i + 1]
return i + 1
def find_kth_largest(arr, k):
# k번째 큰 수를 찾는 함수 (k를 0부터 시작하는 인덱스로 조정)
return quick_select(arr, 0, len(arr) - 1, k - 1)
def heapify(arr, n, i):
"""
주어진 배열을 힙으로 만드는 함수입니다.
"""
largest = i
l = 2 * i + 1
r = 2 * i + 2
if l < n and arr[largest] < arr[l]:
largest = l
if r < n and arr[largest] < arr[r]:
largest = r
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
def heap_sort(arr):
"""
Heap Sort 알고리즘을 구현한 함수입니다.
"""
n = len(arr)
# 주어진 배열을 힙으로 만듭니다.
for i in range(n // 2 - 1, -1, -1):
heapify(arr, n, i)
# 추출한 값을 제외한 나머지 요소들로 다시 힙을 만들고 정렬합니다.
for i in range(n - 1, 0, -1):
arr[0], arr[i] = arr[i], arr[0]
heapify(arr, i, 0)
return arr
def fibo(n):
if n < 2:
return n
return fibo(n - 1) + fibo(n - 2)
def fibo(n, memo):
if memo[n] != 0:
return memo[n]
if n < 2:
return n
memo[n] = fibo(n - 1, memo) + fibo(n - 2, memo)
return memo[n]
memo = [0] * (n + 1)
def fibo(n):
if n < 2:
return n
dp = [0] * (n + 1)
dp[1] = 1
for i in range(2, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]
return dp[n]
def factorial_iterative(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
def factorial_recursive(n):
if n <= 1:
return 1
else:
return n * factorial_recursive(n - 1)
def factorial_memoization(n, memo={}):
if n in memo:
return memo[n]
if n <= 1:
memo[n] = 1
else:
memo[n] = n * factorial_memoization(n - 1, memo)
return memo[n]
def count_trailing_zeros(n):
count = 0
while n >= 5:
count += n // 5
n //= 5
return count
import math
# 소수 판별 함수
def is_prime_number(x):
# 2부터 x의 제곱근까지의 모든 수를 확인하며
for i in range(2, int(math.sqrt(x)) + 1):
# x가 해당 수로 나누어떨어진다면
if x % i == 0:
return False # 소수가 아님
return True # 소수임
import math
n = int(input()) # 2부터 n까지의 모든 수에 대하여 소수 판별
array = [True for i in range(n + 1)] # 처음엔 모든 수가 소수(True)인 것으로 초기화
# 에라토스테네스의 체 알고리즘
for i in range(2, int(math.sqrt(n)) + 1): # 2부터 n의 제곱근까지의 모든 수를 확인하며
if array[i] == True: # i가 소수인 경우 (남은 수인 경우)
# i를 제외한 i의 모든 배수를 지우기
j = 2
while i * j <= n:
array[i * j] = False
j += 1
# 최대공약수 구하기
def gcd(a, b):
# b가 0이면 a가 최대 공약수
if b == 0:
return a
else:
# a를 b로 나눈 나머지를 구하여 재귀호출
return gcd(b, a % b)
# 최소 공배수 = 두 수의 곱을 두 수의 최대공약수로 나눈 값
lcm = a * b // gcd(a, b)
def calculate_ranks(scores):
n = len(scores)
ranks = [1] * n # 모든 학생의 초기 순위를 1로 설정
for i in range(n):
for j in range(n):
if scores[i] < scores[j]: # 다른 점수가 더 높은 경우
ranks[i] += 1 # 현재 학생의 순위를 증가
return ranks
def decimal_to_base(n, base):
if n == 0:
return "0"
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
result = ""
while n > 0:
result = digits[n % base] + result
n = n // base
return result
References
손코딩 테스트 대비
기술 면접 - 손코딩
손코딩 면접 준비
좌충우돌, 파이썬으로 자료구조 구현하기
[Python] 파이썬 정렬 알고리즘 구현 (선택정렬, 삽입정렬, 퀵정렬, 힙정렬, 버블정렬)