[프로그래머스 알고리즘 고득점 Kit][동적계획법(Dynamic Programming)][Java] 사칙연산

2026. 5. 8. 01:21·알고리즘 & 자료구조/문제 풀이

https://school.programmers.co.kr/learn/courses/30/lessons/1843

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

 

 

1. 틀린코드

작은 영역부터 잘라서 왼쪽의 최대 최소, 오른쪽 최대 최소를 이용해 특정 영역의 최댓값을 구한다.

간격이 가장 작은 2부터 0~0 최대 최소 0~2 최대 최소 2~4 ...를 찾아가고
간격이 커지면서 0~4 4~8 .. 이렇게 범위를 늘려간다.

그렇게 되면 N^3의 시간복잡도가 나오는데 시간초과가 떴다.
복잡도를 줄이는 건 도저히 모르겠어서 의심되는 곳을 바꿔보기로 했다.

class Solution {
    public int solution(String arr[]) {
        int len = arr.length;
        int[][] max = new int[len][len];
        int[][] min = new int[len][len];

        for(int i=0; i<len; i+=2) {
            max[i][i] = Integer.parseInt(arr[i]);
            min[i][i] = Integer.parseInt(arr[i]);
        } 
        for(int gap=2; gap<len; gap+=2) {
            for(int start=0; start+gap<len; start+=2) {
                int end = start + gap;
                
                max[start][end] = Integer.MIN_VALUE;
                min[start][end] = Integer.MAX_VALUE;
                
                for(int signIdx=start+1; signIdx<end; signIdx+=2) {
                    int leftMax = max[start][signIdx-1];
                    int leftMin = min[start][signIdx-1];
                    int rightMax = max[signIdx+1][end];
                    int rightMin = min[signIdx+1][end];
                    
                    
                    int candidateMax;
                    int candidateMin;
                    
                    if(arr[signIdx].equals("+")) {
                        candidateMax = leftMax + rightMax;
                        candidateMin = leftMin + rightMin;
                    } else {
                        candidateMax = leftMax - rightMin;
                        candidateMin = leftMin - rightMax;
                    }

                    max[start][end] = Math.max(max[start][end], candidateMax);
                    min[start][end] = Math.min(min[start][end], candidateMin);
                }
            }
        }
        
        return max[0][len-1];
    }
}


병목이 가장 의심되는 부분은 문자열 연산이었다. equals를 char == 비교로 바꿔보자.

if(arr[signIdx].charAt(0) == '+') {
                        candidateMax = leftMax + rightMax;
                        candidateMin = leftMin + rightMin;
                    } else {
                        candidateMax = leftMax - rightMin;
                        candidateMin = leftMin - rightMax;
                    }

평균 시간은 줄었으나 결과는 똑같았다.
두번째 의심되는 곳은 문자열 배열이었다.
클래스 배열이기 때문에 하나의 인덱스마다 참조 접근을 하기 때문에 느릴 수 있다고 판단했다.
게다가 N^3 반복문 안에서 문자열 배열 인덱스 접근 -> 참조접근 -> charAt() 호출 -> 비교연산으로 충분히 의심할만하다.

그래서 기호 문자열을 미리 char 배열로 빼두고 다시.

 

2. 정답코드

class Solution {
    public int solution(String arr[]) {
        int len = arr.length;

        char[] ops = new char[len];

        for (int i = 1; i < len; i += 2) {
            ops[i] = arr[i].charAt(0);
        }

        int[][] max = new int[len][len];
        int[][] min = new int[len][len];

        for(int i=0; i<len; i+=2) {
            max[i][i] = Integer.parseInt(arr[i]);
            min[i][i] = Integer.parseInt(arr[i]);
        } 

        for(int gap=2; gap<len; gap+=2) {
            for(int start=0; start+gap<len; start+=2) {
                int end = start + gap;
                
                max[start][end] = Integer.MIN_VALUE;
                min[start][end] = Integer.MAX_VALUE;
                
                for(int signIdx=start+1; signIdx<end; signIdx+=2) {
                    int leftMax = max[start][signIdx-1];
                    int leftMin = min[start][signIdx-1];
                    int rightMax = max[signIdx+1][end];
                    int rightMin = min[signIdx+1][end];
                    
                    int candidateMax;
                    int candidateMin;
                    
                    if(ops[signIdx] == '+') {
                        candidateMax = leftMax + rightMax;
                        candidateMin = leftMin + rightMin;
                    } else {
                        candidateMax = leftMax - rightMin;
                        candidateMin = leftMin - rightMax;
                    }

                    max[start][end] = Math.max(max[start][end], candidateMax);
                    min[start][end] = Math.min(min[start][end], candidateMin);
                }
            }
        }
        
        return max[0][len-1];
    }
}
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 & 자료구조 > 문제 풀이' 카테고리의 다른 글

[프로그래머스 알고리즘 고득점 Kit][그리디][Java] 체육복  (0) 2026.04.30
[프로그래머스 알고리즘 고득점 Kit][정렬][Java] 가장 큰 수  (0) 2026.04.28
[프로그래머스 알고리즘 고득점 Kit][깊이/너비 우선 탐색(DFS/BFS)][Java] 아이템 줍기  (0) 2026.04.28
[프로그래머스 알고리즘 고득점 Kit][깊이/너비 우선 탐색(DFS/BFS)][Java] 여행경로  (0) 2026.04.27
[LeetCode][Java][영어공부] 1071. Greatest Common Divisor of Strings  (0) 2026.04.24
'알고리즘 & 자료구조/문제 풀이' 카테고리의 다른 글
  • [프로그래머스 알고리즘 고득점 Kit][그리디][Java] 체육복
  • [프로그래머스 알고리즘 고득점 Kit][정렬][Java] 가장 큰 수
  • [프로그래머스 알고리즘 고득점 Kit][깊이/너비 우선 탐색(DFS/BFS)][Java] 아이템 줍기
  • [프로그래머스 알고리즘 고득점 Kit][깊이/너비 우선 탐색(DFS/BFS)][Java] 여행경로
수수다
수수다
우하하
  • 수수다
    그냥살자
    수수다
  • 전체
    오늘
    어제
    • 분류 전체보기 (63)
      • 프로젝트 (1)
      • 알고리즘 & 자료구조 (30)
        • 내용 정리 (2)
        • 문제 풀이 (28)
      • 데이터베이스 (27)
        • 내용 정리 (1)
        • 문제 풀이 (26)
      • CS (2)
      • 기타 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 네이버 블로그
  • 공지사항

  • 인기 글

  • 태그

    프로그래머스 알고리즘 고득점 kit
    정렬
    IFNULL
    그래프
    분리집합
    바이브코딩
    코딩테스트
    이분탐색
    코팅테스트
    동적계획법
    like
    알고리즘
    bfs
    매개변수탐색
    DP
    HTTP 메서드
    date_format
    삼성청년SW·AI아카데미
    유니온파인드
    프로그래머스
    깊이/너비 우선 탐색(DFS/BFS)
    coalesce
    코테
    mysql
    해시
    바킹독
    Java
    AVG
    SQL
    Round
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
수수다
[프로그래머스 알고리즘 고득점 Kit][동적계획법(Dynamic Programming)][Java] 사칙연산
상단으로

티스토리툴바