[알고리즘] 자주 출제되는 기타 알고리즘

2024. 10. 20. 12:00·코딩테스트 대비
728x90

 

 

 

1. 소수 판별 알고리즘

✨ 정의

1보다 큰 자연수 중에서 1과 자기 자신을 제외한 자연수로는 나누어떨어지지 않는 자연수

 

 

✨ 기본적인 알고리즘 

 

# 소수 판별 함수 (2 이상의 자연수에 대하여)
def is_prime_number(x):
    # 2부터 (x - 1)까지의 모든 수를 확인하며
    for i in range(2, x):
        # x가 해당 수로 나누어떨어진다면
        if x % i == 0:
            return False    # 소수가 아님
    return True # 소수임


print(is_prime_number(4))   # False
print(is_prime_number(7))   # True
  • 2부터 $X - 1$까지의 모든 자연수에 대하여 연산을 수행해야 하므로, 시간 복잡도는 $O(X)$입니다.

 

 

✨ 약수의 성질을 활용한 알고리즘

모든 약수가 가운데 약수를 기준으로 곱셈 연산에 대해 대칭을 이루는 것을 알 수 있습니다.
따라서 특정한 자연수의 모든 약수를 찾을 대 가운데 약수(제곱근)까지만 확인하면 됩니다.

 

 

import math

# 소수 판별 함수 (2 이상의 자연수에 대하여)
def is_prime_number(x):
    # 2부터 (x - 1)까지의 모든 수를 확인하며
    for i in range(2, int(math.sqrt(x)) + 1):
        # x가 해당 수로 나누어떨어진다면
        if x % i == 0:
            return False    # 소수가 아님
    return True # 소수임


print(is_prime_number(4))   # False
print(is_prime_number(7))   # True

 

 

 

2. 에라토스테네스의 체 

✨ 정의

다수의 자연수에 대하여 소수 여부를 판별할 때 사용하는 대표적인 알고리즘입니다.
N보다 작거나 같은 모든 소수를 찾을 때 사용할 수 있습니다.

 

  1. 2부터 N까지의 모든 자연수를 나열한다.
  2. 남은 수 중에서 아직 처리하지 않은 가장 작은 수 i를 찾는다.
  3. 남은 수 중에서 i의 배수를 모두 제거한다 (i는 제거하지 않는다).
  4. 더 이상 반복할 수 없을 때까지 2번과 3번의 과정을 반복한다.

 

 

✨ 동작 예시

 

 

 

✨ 구현

import math

n = 1000    # 2부터 1000까지의 모든 수에 대하여 소수 판별
# 처음엔 모든 수가 소수(True)인 것으로 초기화 (0과 1은 제외)
array = [True for i in range(n + 1)]

# 에라토스테네스의 체 알고리즘 수행
# 2부터 n의 제곱근까지의 모든 수를 확인하며
for i in range(2, int(math.sqrt(n)) + 1):
    if array[i] == True:    # i가 소수인 경우 (남은 수인 경우)
        # i를 제외한 i의 모든 배수 지우기
        j = 2
        while i * j <= n:
            array[i * j] = False
            j += 1

# 모든 소수 출력
for i in range(2, n + 1):
    if array[i]:
        print(i, end=" ")
  • 시간 복잡도는 $O(N \log(\log N))$입니다.
  • 다수의 소수를 찾아야 하는 문제에서 효과적으로 사용할 수 있으나, 각 자연수에 대한 소수 여부를 저장해야 하므로 메모리가 많이 필요합니다.

 

 

 

3. 투 포인터 (Two Pointers)

✨ 정의

리스트에 순차적으로 접근해야 할 때 두 개의 점의 위치를 기록하면서 처리하는 알고리즘
  • 리스트에 담긴 데이터에 순차적으로 접근해야 할 때는 시작점과 끝점 2개의 점으로 접근할 데이터의 범위를 표현할 수 있습니다.

 

 

✨ 특정한 합을 가지는 부분 연속 수열 찾기

N개의 자연수로 구성된 수열이 있습니다.
합이 M인 부분 연속 수열의 개수를 구해보세요.
수행 시간 제한은 $O(N)$입니다.

 

 

  • 아이디어: 투 포인터를 활용
    1. 시작점(start)과 끝점(end)이 첫 번째 원소의 인덱스(0)을 가리키도록 한다.
    2. 현재 부분 합이 M과 같다면, 카운트한다.
    3. 현재 부분 합이 M보다 작다면, end를 1 증가시킨다.
    4. 현재 부분 합이 M보다 크거나 같다면, start를 1증가시킨다.
    5. 모든 경우를 확인할 때까지 2번부터 4번까지의 과정을 반복한다.

 

  • 구현
n = 5   # 데이터의 개수 N
m = 5   # 찾고자 하는 부분합 M
data = [1, 2, 3, 2, 5]  # 전체 수열

count = 0
interval_sum = 0
end = 0

# start를 차례대로 증가시키며 반복
for start in range(n):
    # end를 가능한 만큼 이동시키기
    while interval_sum < m and end < n:
        interval_sum += data[end]
        end += 1
    # 부분합이 m일 때 카운트 증가
    if interval_sum == m:
        count += 1
    interval_sum -= data[start]

print(count)    # 3

 

 

 

4. 구간 합 (Interval Sum)

✨ 정의

연속적으로 나열된 N개의 수가 있을 때 특정 구간의 모든 수를 합한 값을 계산하는 문제

 

 

✨ 문제

N개의 정수로 구성된 수열이 있습니다.

M개의 쿼리(Query) 정보가 주어집니다. 각 쿼리는 Left와 Right으로 구성됩니다. 각 쿼리에 대하여 [Left, Right] 구간에 포함된 데이터들의 합을 출력해야 합니다.

수행 시간 제한은 $O(N + M)$입니다.

 

  • 아이디어: 배열의 맨 앞부터 특정 위치까지의 합을 미리 구해 놓은 것인 접두사 합(Prefix Sum)을 활용합니다.
    • N개의 수 위치 각각에 대하여 접두사 합을 계산하여 P에 저장합니다.
    • 매 M개의 쿼리 정보를 확인할 때 구간 합은 P[Right] - P[Left - 1]

 

 

 

  • 답안
# 데이터의 개수 N과 데이터 입력받기
n = 5
data = [10, 20, 30, 40, 50]

# 접두사 합(Prefix Sum) 배열 계산
sum_value = 0
prefix_sum = [0]
for i in data:
    sum_value += i
    prefix_sum.append(sum_value)

# 구간 합 계산 (세 번째 수부터 네 번째 수까지)
left = 3
right = 4
print(prefix_sum[right] - prefix_sum[left - 1]) # 70

 

 

 

728x90

'코딩테스트 대비' 카테고리의 다른 글

[파이썬(Python)] 백준 2588번 곱셈  (0) 2024.10.22
[알고리즘] 다이나믹 프로그래밍 (Dynamic Programming)  (0) 2024.10.20
[알고리즘] 이진 탐색 (Binary Search)  (1) 2024.10.18
[알고리즘] 정렬 알고리즘  (0) 2024.10.18
[알고리즘] 깊이 우선 탐색(DFS)과 너비 우선 탐색(BFS)  (0) 2024.10.17
'코딩테스트 대비' 카테고리의 다른 글
  • [파이썬(Python)] 백준 2588번 곱셈
  • [알고리즘] 다이나믹 프로그래밍 (Dynamic Programming)
  • [알고리즘] 이진 탐색 (Binary Search)
  • [알고리즘] 정렬 알고리즘
랑뎁
랑뎁
  • 랑뎁
    RangDev.
    랑뎁
  • 전체
    오늘
    어제
    • 분류 전체보기 (270)
      • 취준 (59)
        • 경제신문스크랩 (59)
      • 파이썬 (2)
      • 코딩테스트 대비 (168)
      • 수학 (2)
      • 머신러닝 (0)
      • 컴퓨터비전 (1)
      • 강화학습 (33)
      • Git (3)
      • 자격증 (1)
        • 한국사 능력 검정 1급 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 인기 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.2
랑뎁
[알고리즘] 자주 출제되는 기타 알고리즘
상단으로

티스토리툴바