합병 정렬(Merge Sort)

- Divide : 리스트를 반으로 나눈다

- Conquer : 왼쪽 리스트와 오른쪽 리스트를 각각 정렬한다

- Combine : 정렬된 두 리스트를 비교하여 하나의 정렬된 리스트로 합병한다 

 

퀵 정렬(Quick Sort)

- Divide : partition을 하는 과정 

- Conquer : pivot 왼쪽에 있는 값들과 pivot 오른쪽에 있는 값들을 각각 정렬 

- Combine : 정렬된 두 리스트를 하나의 정렬된 리스트로 합병한다

 

[프로그래머스] K번째 수 -  lv.1

 


[프로그래머스] 가장 큰 수 - lv.2

 


[프로그래머스] H-index - lv.2

 

스택/큐 (Stack/Queue)

- 스택과 큐는 데이터 순서관계를 유지할 수 있다.

[프로그래머스] 같은 숫자는 싫어 - lv.1

from collections import deque

def solution(arr):
    queue = deque(arr)
    
    answer = []
    answer.append(queue.popleft())  
    
    while queue:
        temp = queue.popleft()
        if temp != answer[-1]:
            answer.append(temp)
            
    return answer

[프로그래머스] 기능개발 - lv.2

- 사칙연산을 이용하면 오류나니까 math.ceil 이용할 것 

- (remain)//speed + 1 로 쓰면 int로 정확히 나올 경우에도 +1해주므로 오답

from collections import deque
import math

def solution(progresses, speeds):
    
    queue = deque(progresses)
    answer = []
    i = 0
    time = 0
    fin = 0
    
    while queue:
        
        job = queue.popleft()
        speed = speeds[i]
        job = job + time*speed
                   
        
        if job >= 100:
            fin += 1
        else:
            answer.append(fin)
            fin = 0
            
            remain = 100 - job
            plus_time = math.ceil(remain/speed)
            time += plus_time
            fin += 1
            
        i += 1
        
    answer.append(fin)
    print(answer)
    return answer[1:]

[프로그래머스] 올바른 괄호 - lv.2

 

 

 

 

'Programming > 알고리즘' 카테고리의 다른 글

[Python] 정렬 Sort  (0) 2024.10.23
[Python] 탐욕법 (Greedy)  (0) 2024.10.20
[Python] 동적 계획법 (Dynamic Programming)  (1) 2024.10.17
[Python] 이진 탐색 (Binary Search)  (0) 2024.10.14

탐욕법 (Greedy)

- 당장 눈앞에 보이는 최적의 선택을 하는 방식

- 각 단계에서 탐욕스러운 선택이 최종 답을 구하기 위한 최적의 선택 

- 전체에서 최적의 답이 아닐 수도 있음

ex) 매 순간마다 가장 큰 동전을 선택 

## 최소 동전으로 거슬러 주기 ##
def min_coin_count(value, coin_list):
    count = 0
    while value != 0:
        coin_list.sort(reverse=True)
        for i in range(4):
            count += (value//coin_list[i])
            value = (value%coin_list[i])
    return count

default_coin_list = [100, 500, 10, 50]
print(min_coin_count(1440, default_coin_list))

 


[프로그래머스] 체육복

- 여분 체육복을 가진 친구 먼저 제외

def solution(n, lost, reserve):
    
    answer = n-len(lost)
    
    lost.sort()
    lost2 = []
    
    
    for i in range(len(lost)):
        
        if lost[i] in reserve:
            answer += 1
            reserve.remove(lost[i]) 
        else:
            lost2.append(lost[i])
            
    for i in range(len(lost2)):
        if lost2[i]-1 in reserve:
            answer += 1
            reserve.remove(lost2[i]-1)    
        elif lost2[i]+1 in reserve:
            answer += 1  
            reserve.remove(lost2[i]+1) 

    return answer

[프로그래머스] 큰 수 만들기

- 두 번의 반복문을 사용하면 비효율적 + 시간초과

- "스택"을 사용하여 숫자를 쌓아가기 

- k는 제거해야하는 숫자 개수 

"""오답"""

def solution(number, k):
    
    N = len(number) - k
    num_lst = list(number)
    
    while len(num_lst) != N:
        i = 0
        for i in range(len(num_lst)):
            if int(num_lst[i]) < int(num_lst[i+1]):
                num_lst.pop(i)
                break
                
    return ''.join(num_lst)
"""변경 답안"""
from collections import deque

def solution(number, k):
    
    stack = []
    
    for i in range(len(number)):
        while stack and k>0 and int(stack[-1])<int(number[i]):
            stack.pop()
            k -= 1
        stack.append(number[i])
   
    
    if k>0:
        return ''.join(stack)[:-k]
    else:
        return ''.join(stack)

[프로그래머스] 조이스틱

'Programming > 알고리즘' 카테고리의 다른 글

[Python] 정렬 Sort  (0) 2024.10.23
[Python] 스택/큐 (Stack/Queue)  (0) 2024.10.20
[Python] 동적 계획법 (Dynamic Programming)  (1) 2024.10.17
[Python] 이진 탐색 (Binary Search)  (0) 2024.10.14

동적 계획법 (Dynamic Programming)

- 한번 계산한 결과를 재활용하는 것 

 

1. Memorization

-  재귀함수 사용

-  다시 쓸값을 저장해놓는 공간을 cache(캐시)라고 함

Recursive case: 현 문제가 너무 커서, 같은 형태의 더 작은 부분 문제를 재귀적으로 푸는 경우

-  Base case: 이미 문제가 충분히 작아서, 더 작은 부분 문제로 나누지 않고도 바로 답을 알 수 있는 경우

""" 1부터 n까지의 합 """

def consecutive_sum(start, end):

    # base case        
    if end == start:
        return start

    # 부분 문제를 반으로 나눠주기 위해서 문제의 정중앙을 정의한다 (Divide)
    mid = (start + end) // 2

    # 각 부분 문제를 재귀적으로 풀고(Conquer), 부분 문제의 답을 서로 더한다(Combine).
    return consecutive_sum(start, mid) + consecutive_sum(mid + 1, end)

 

2. Tabulation

-  단순 반복문 사용 

-  Table 방식으로 정리

 


[프로그래머스] N으로 표현

- 숫자 N과 number가 주어질 때, N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return

# i: 숫자 N을 몇번 사용할지 -> i별로 나올 수 있는 숫자 dp(list)에 저장 
# dp[i]를 만들기 위해서는 dp[j]와 dp[i-j]의 값을 결합해야만 더 많은 경우의 수를 고려

def iter_func(N, i, dp):
    
    for j in range(1, i):
        
        for num1 in dp[j]:
            for num2 in dp[i-j]:
                
                if num1+num2 <= 32000:
                    dp[i].add(num1+num2)
                if num1-num2 <= 32000:
                    dp[i].add(num1-num2)
                if num1*num2 <= 32000:
                    dp[i].add(num1*num2)
                if (num2!=0) and (num1//num2 <= 32000):
                    dp[i].add(num1//num2)
                    
    dp[i].add(int(str(N)*i))
    
    return dp


def solution(N, number):
    
    dp = [set() for _ in range(9)]
    
    for i in range(1, 9):
        dp = iter_func(N, i, dp)
        
        if number in dp[i]:
            return i
            
    return -1

[프로그래머스] 정수 삼각형

-  대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동하여 최댓값 구하기 

def iter_func(triangle, h, max_cache):
    now = max_cache[h]
    next_line = triangle[h+1]
    
    # 다음 줄에 값을 최대값으로 갱신 # 위치가 겹침
    for i in range(len(now)):
        max_cache[h+1][i] = max(max_cache[h+1][i], now[i] + next_line[i])
        max_cache[h+1][i+1] = max(max_cache[h+1][i+1], now[i] + next_line[i+1])

    return max_cache
            
    
def solution(triangle):
    max_cache = {}
    
    # 캐시 초기화
    for h in range(len(triangle)):
        max_cache[h] = [0] * len(triangle[h])
    
    max_cache[0][0] = triangle[0][0]
    
    for h in range(len(triangle)-1):
        max_cache = iter_func(triangle, h, max_cache)
    
    return max(max_cache[len(triangle)-1])

[프로그래머스] 등굣길

- 웅덩이를 피해 오른쪽과 아래쪽으로만 움직여 집에서 학교까지 갈 수 있는 최단경로의 개수를 1,000,000,007로 나눈 나머지를 return

# [x][y]: 해당좌표까지의 경로 계산 

def iter_func(puddles, x, y, dp):
    
    path = 0
    if ([x-1,y] not in puddles) and ((x-1)>=0):
        path += dp[x-1][y] 
    if ([x,y-1] not in puddles) and ((y-1)>=0):
        path += dp[x][y-1]

    dp[x][y]  = path
        
    return dp


def solution(m, n, puddles):
    
    dp = [[0]*n for _ in range(m)]
    dp[0][0] = 1
    
    puddles = [[p[0] - 1, p[1] - 1] for p in puddles]
    
    for y in range(n):
        for x in range(m):
            
            if [x,y] == [0,0]:
                continue
            
            if [x,y] in puddles:
                continue
            else:
                dp = iter_func(puddles, x, y, dp)
            
    return dp[m-1][n-1] % 1000000007

 

 

'Programming > 알고리즘' 카테고리의 다른 글

[Python] 정렬 Sort  (0) 2024.10.23
[Python] 스택/큐 (Stack/Queue)  (0) 2024.10.20
[Python] 탐욕법 (Greedy)  (0) 2024.10.20
[Python] 이진 탐색 (Binary Search)  (0) 2024.10.14

이진 탐색 (Binary Search)

-  정렬된 리스트를 전제로 진행

-  (Start, End, Mid) 변수 2개를 사용하여 탐색

-  중간 지점을 보고, 왼쪽 or 오른쪽을 버림

-  (추가) 제한조건이 무지막지하게 큰 숫자이면 이진 탐색 문제임을 알 수 있다.

def binary_search(element, some_list):

    some_list.sort()
    start_num = 0
    end_num = len(some_list)-1
    
    while start_num <= end_num:
        temp = (start_num+end_num)//2
        
        if some_list[temp] == element:
            return temp
        elif some_list[temp] > element:
            end_num = temp-1
        else:
            start_num = temp+1
            
    return None


print(binary_search(2, [2, 3, 5, 7, 11]))

 

[프로그래머스] 입국심사

-  모든 사람을 심사할 수 있는 가장 작은 시간을 찾는 것

-  전체 심사위원이 mid시간동안 심사할 수 있는 사람의 수가 전체 사람의 수(n)와 같아지는 mid값을 찾는 것이 해답

[프로그래머스] 징검다리

바위 사이의 간격의 최솟값이 최대화되고자 하므로, 바위사이의간격을 기준으로 두고 문제를 풀어야 한다.

 

Python 이진 탐색 라이브러리: bisect

'Programming > 알고리즘' 카테고리의 다른 글

[Python] 정렬 Sort  (0) 2024.10.23
[Python] 스택/큐 (Stack/Queue)  (0) 2024.10.20
[Python] 탐욕법 (Greedy)  (0) 2024.10.20
[Python] 동적 계획법 (Dynamic Programming)  (1) 2024.10.17

+ Recent posts