개발자 기술면접 꼬리물기 질문
  • Welcome
  • 01 Java
    • 01-01. Generic
    • Garbage Collection
    • 자료형과 객체 비교
    • 힙(Heap)과 메모리(Memory)
    • JDK 버전과 JRE
    • 스레드(Thread)
    • 예외(Throwable)
    • Call By Value와 Call By Reference
    • String, equals, StringBuffer
    • Thread와 비동기
  • 02 Spring
    • 02-01. Spring 동작 방식
    • @Autowired, @RequiredArgsConstructor
    • 인증(Authentication)과 인가(Authorization)
    • 트랜잭션(Transaction)
    • QueryDSL과 SQL Injection
    • SecurityContextHolder
    • @EqualsAndHashCode
  • 알고리즘과 자료구조
    • Set 자료구조
    • 정렬 알고리즘
    • 우선순위 큐 (Priority Queue)
    • DFS와 BFS
    • 힙(Heap) 자료구조
    • 스택(Stack)과 큐(Queue)
    • 암호화 알고리즘
    • LinkedList
    • 자료구조 - 해시 테이블(HashTable)
    • 자료구조 - ConcurrentHashMap
  • 데이터베이스
    • 기본
    • 인덱스 (Index)
    • 정규화 (Normalization)
    • 파티셔닝과 샤딩(Partitioning & Sharding)
    • 트랜잭션(Transaction)과 락(Lock)
    • 덤프(Dump)
    • Redis
    • 격리 수준(MySQL)
  • 네트워크
    • 전송 계층 (Transport Layer)
    • 네트워크 계층 (Network Layer)
    • Http와 Https
    • IP(Internet Protocol)
    • 프록시 서버
    • Http Protocol
    • 소켓(Socket)
    • 로드 밸런싱(Load Balancing)
  • 디자인 패턴
    • 전략 패턴 (Strategy Pattern)
    • 싱글톤 패턴 (Singleton Pattern)
    • 템플릿 메서드 패턴과 전략 패턴
    • 데코레이터 패턴 (Decorator pattern)
  • 웹
    • CORS 정책
    • 동시성 제어
    • N+1 문제
    • 웹 브라우저 동작원리
    • URI, URL, URN
    • 채팅 아키텍처 설계
  • 개발자
    • 개발 방법론 TDD
  • 운영체제
    • JIT & AOT 컴파일
    • 컨텍스트 스위칭(Context Switching)
    • 프로세스와 스레드
    • 싱글 스레드와 멀티 스레드
  • 코딩테스트
    • Stack / Queue (스택 / 큐)
    • Heap(우선 순위 큐)
    • DP(동적 계획법)
    • DFS(깊이 우선 탐색)
    • BFS(너비 우선 탐색)
    • Greedy(그리디 알고리즘)
    • 해시(Hash)
    • 투 포인터 알고리즘
    • Shortest path
    • 수학적 사고
Powered by GitBook
On this page
  • 0. DP 문제 특징
  • 1. 스티커 모으기(2)
  • 2. N으로 표현
  • 3. 정수 삼각형
  • 4. 등굣길
  1. 코딩테스트

DP(동적 계획법)

불필요한 계산을 줄이고, 효율적으로 최적해를 찾아야만 풀리는 문제들입니다.

PreviousHeap(우선 순위 큐)NextDFS(깊이 우선 탐색)

Last updated 5 months ago

0. DP 문제 특징

  • 최적화(최소, 최대, 최적) 문제

  • 메모이제이션(이전 계산한 결과를 저장하고 재사용 가능한) 문제

  • 작은 문제의 해답들이 큰 문제의 해답을 구성하는 문제

  • 피보나치 수열과 같은 점화식 문제

1. 스티커 모으기(2)

  • 프로그래머스 Lv.3 / 체감 난이도 Lv.2

  • 두 가지 케이스를 나눠서 해를 찾는 문제

class Solution {
    public int solution(int sticker[]) {
        int n = sticker.length;
        
        // 스티커가 1장인 경우
        if (n == 1) return sticker[0];
        // 스티커가 2장인 경우
        if (n == 2) return Math.max(sticker[0], sticker[1]);
        
        // 첫 번째 스티커를 선택하는 경우 (마지막 스티커는 선택 불가)
        int[] dp1 = new int[n];
        dp1[0] = sticker[0];
        dp1[1] = sticker[0];  // 두 번째는 선택 불가
        for (int i = 2; i < n-1; i++) {
            dp1[i] = Math.max(dp1[i-1], dp1[i-2] + sticker[i]);
        }
        
        // 첫 번째 스티커를 선택하지 않는 경우 (마지막 스티커 선택 가능)
        int[] dp2 = new int[n];
        dp2[0] = 0;  // 첫 번째는 선택하지 않음
        dp2[1] = sticker[1];
        for (int i = 2; i < n; i++) {
            dp2[i] = Math.max(dp2[i-1], dp2[i-2] + sticker[i]);
        }
        
        return Math.max(dp1[n-2], dp2[n-1]);
    }
}

2. N으로 표현

  • 프로그래머스 Lv.3 / 체감 난이도 Lv.3

  • N을 1~8번 사용했을 때 만들 수 있는 모든 숫자를 점진적으로 계산

import java.util.*;

class Solution {
    public int solution(int N, int number) {
        if (N == number) {
            return 1;
        }
        // 각 횟수별로 만들 수 있는 수의 집합을 저장할 배열
        Set<Integer>[] dp = new Set[9];
        
        for (int i = 1; i <= 8; i++) {
            dp[i] = new HashSet<>();
        }
        
        // N을 i번 사용해서 만들 수 있는 값을 미리 저장
        int baseNumber = N;
        for (int i = 1; i <= 8; i++) {
            dp[i].add(baseNumber);
            baseNumber = baseNumber * 10 + N;
        }
        
        // 1부터 8까지 경우를 살펴보며 가능한 값을 만듦
        for (int i = 1; i <= 8; i++) {
            for (int j = 1; j < i; j++) {
                for (int x : dp[j]) {
                    for (int y : dp[i - j]) {
                        dp[i].add(x + y);
                        dp[i].add(x - y);
                        dp[i].add(x * y);
                        if (y != 0) {
                            dp[i].add(x / y);
                        }
                    }
                }
            }            
            
            // number를 찾으면 바로 return
            if (dp[i].contains(number)) {
                return i;
            }
        }
        
        return -1; // 8번 이내에 만들 수 없을 경우
    }
}

3. 정수 삼각형

  • 프로그래머스 Lv.3 / 체감 난이도 Lv.3

import java.util.*;

class Solution {
    public int solution(int[][] triangle) {
        int n = triangle.length;
        
        // 삼각형의 마지막 층을 복사하여 dp 배열로 사용
        int[] dp = new int[n];
        for (int i = 0; i < n; i++) {
            dp[i] = triangle[n - 1][i];
        }
        
        // 아래에서부터 위로 올라가며 최대 경로 계산
        for (int i = n - 2; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                dp[j] = Math.max(dp[j], dp[j + 1]) + triangle[i][j];
            }
        }
        
        // dp[0]에 최종 결과가 저장됨
        return dp[0];
    }
}

4. 등굣길

  • 문제 링크

  • 프로그래머스 Lv.3 / 체감 난이도 Lv.4

class Solution {
    public int solution(int m, int n, int[][] puddles) {
        int[][] street = new int[n][m];
        
        // 웅덩이는 -1
        for (int[] puddle : puddles) {
            street[puddle[1]-1][puddle[0]-1] = -1;
        }
        
        street[0][0] = 1;
        
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if(street[i][j] == -1) { // 웅덩이면 0으로 바꾸고 continue
                  street[i][j] = 0;
                  continue;
                }
                
                if(i != 0) {
                    street[i][j] += street[i - 1][j] % 1000000007; 
                }

                if(j != 0) {
                    street[i][j] += street[i][j - 1] % 1000000007;   
                }
            }
        }
        
        return street[n - 1][m - 1] % 1000000007;
    }
}

문제 링크
문제 링크
문제 링크