코딩테스트/프로그래머스 level 3

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

냠냠:) 2020. 4. 13. 00:20

https://programmers.co.kr/learn/courses/30/lessons/43105

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

[문제 설명]

위와 같은 삼각형의 꼭대기에서 바닥까지 이어지는 경로 중, 거쳐간 숫자의 합이 가장 큰 경우를 찾아보려고 합니다. 아래 칸으로 이동할 때는 대각선 방향으로 한 칸 오른쪽 또는 왼쪽으로만 이동 가능합니다. 예를 들어 3에서는 그 아래칸의 8 또는 1로만 이동이 가능합니다.

삼각형의 정보가 담긴 배열 triangle이 매개변수로 주어질 때, 거쳐간 숫자의 최댓값을 return 하도록 solution 함수를 완성하세요.

 

제한사항

  • 삼각형의 높이는 1 이상 500 이하입니다.
  • 삼각형을 이루고 있는 숫자는 0 이상 9,999 이하의 정수입니다.

입출력 예

triangle result
[[7], [3, 8], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]] 30

 

[풀이]

1. 배열의 어떤 곳이든 양 끝에 위치한 값들은 바로 위에서 내려오는 값에 의해서만 영향이 받으므로 양 끝에 위치한 값들을 업데이트한다.

2. 양 끝을 제외한 중간 값들은 자신이 가지고 있는 인덱스 [i][j]가 있다면 [i-1][j-1]와 [i-1][j]의 값 중 큰 것을 골라 업데이트해준다.

triangle[2][1]값인 1을 보면 [i-1][j-1] 값과 [i-1][j] 값 중에 큰 것을 받아야 한다.

3. 1, 2번을 반복해주고 마지막 라인에 있는 배열에서 가장 큰 값을 반환한다.

 

[코드]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    public int solution(int[][] triangle) {
        for(int i = 0; i < triangle.length-1; i++) {            //i에 +1을 하는 계산식이 있으므로 length -1을 해준다.
            triangle[i+1][0+= triangle[i][0];                    //양 끝에 있는 수를 먼저 업데이트 시킨다.
            triangle[i+1][triangle[i+1].length-1+= triangle[i][triangle[i].length-1];
            for(int j = 1; j <= triangle[i+1].length -2; j++) {    //중앙 값들을 업데이트 시킨다.
                if(triangle[i][j-1< triangle[i][j]) {            //자신보다 위에 있는 두개의 수 중 큰 값으로 업데이트 해준다.
                    triangle[i+1][j] += triangle[i][j];
                }else {
                    triangle[i+1][j] += triangle[i][j-1];
                }
            }
        }
        
        int answer = 0;
        for(int i = 0; i < triangle[triangle.length-1].length; i++) {    //max값을 찾는 과정
            if(answer < triangle[triangle.length-1][i]) {
                answer = triangle[triangle.length-1][i];
            }
        }
        return answer;
    }
cs

프로그래머스 테스트 케이스 통과

[개선된 코드]

1
2
3
4
5
6
7
8
9
10
11
public int solution(int[][] triangle) {
        for(int i = 0; i < triangle.length-1; i++) {            //i에 +1을 하는 계산식이 있으므로 length -1을 해준다.
            triangle[i+1][0+= triangle[i][0];                    //양 끝에 있는 수를 먼저 업데이트 시킨다.
            triangle[i+1][i+1+= triangle[i][i];
            for(int j = 1; j <= i; j++) {    //중앙 값들을 업데이트 시킨다.
                triangle[i+1][j] += Math.max(triangle[i][j-1], triangle[i][j]);
            }
        }
        
        return Arrays.stream(triangle[triangle.length-1]).max().getAsInt();
    }
cs

** 해당 문제를 풀고 난 후 다른 사람 풀이를 보고 감명받아 내가 푼 문제를 개선해봤다.

 

느낀 점: 나한테 DP는 항상 알듯 말듯한 문제이다. 항상 처음 문제를 직면했을 때 문제 풀이 방식을 여러 방향으로 생각하지만 DP는 너무 많은 방향으로 생각이 드는 것 같다. 경험 부족일 것이고 앞으로 더 많이 DP문제를 풀어봐야겠다는 생각이 든다.

 

**피드백은 언제나 환영입니다!

 

반응형