[프로그래머스]Lv2.파헤치기 자바(Java) 마법의 엘리베이터

Wang_Seok_Hyeon·2023년 4월 13일
0
post-thumbnail

오늘 준비한 코드부터 보시죠.

class Solution {
    public int solution(int storey) {
        return elevator(storey);
    }
    private int elevator(int floor){
        if(floor<=1) return floor;//종료조건. 1보다 작으면 가능성이 없음
        int remainer = floor % 10;
        int newFloor = floor / 10;
        
        int c1 = remainer + elevator(newFloor); //올라가는 경우
        int c2 = (10-remainer) + elevator(newFloor+1);//내려가는 경우
        return Math.min(c1,c2);
    }
}

스트림을 제외하고는 가장 짧은 방식 중 하나로 작성된 것 같습니다.

해당 문제를 고려할 때,
최초에는 5를 기준으로 5이하면 내리고 5보다 크면 올리면 되겠네.
이런 생각을 했습니다.

하지만 위의 생각은 어리석은 생각이며, 많은 분들이 어렵지 않게
구현하셨으리라 생각됩니다.

하지만 그렇게 작성될 경우 틀리게 되는데 이유는 아래와 같은 예제 때문입니다.

95 다음과 같은 수의 경우 5라고 해서 내리게 되면 올렸을 때 얻는 이점을 잃게 됩니다.
즉 5을 올림 해주고 이를 통해 다음 수가 자리 올림이 발생한다면
5의 경우더라도 자리 올림을 할 필요가 있습니다.
(5 기준으로 내리고, 5보다 크면 올릴 때 최초 5 = 버림(5회))
(남은 9의 경우 5보다 크므로 올림 '1번 올림.' 자리수가 바뀜에 따라 carry(올림수)에 의해 +1회 총 7회)
(5여도 올린다면. + 5, 이에 따라 9가 자리 올림되어 100 1번만 실행해주면 됨 총 6회)

이처럼 9뿐만 아니라 자리 올림이 이점이 되는 수인 6보다 큰 수들이라면,
5라도 자리 올림을 해주는 것이 이점이 됩니다!

하지만 위와 같이 코드를 작성하게 되면 코드가 길어지기 때문에
생각을 조금 바꿔 봅니다.

올라가는 경우, 내려가는 경우로 2가지를 축소하고 해당 경우의 케이스들 중 가장 작은 경우를
선택해 더해주는 재귀의 구현입니다. 해당 구현의 경우 dfs와 유사한 형태이기도 합니다.
값을 줄여나가며 해당 경우의 수 아래로 깊게 파고 들어가는 형태기 때문이죠.

다만 재귀 함수 구현에서 여전히 쉽지 않은 부분이 종료부분이자 반환값을
설정해 주는 부분입니다. 특히나 마지막 함수가 끝났을 때 어떤 것을 반환하는 게 좋은가에서
문제의 조건에 맞게 가장 큰 값이냐, 가장 작은 값이냐의 유형을 나눠서 문제의 답을
도출해 주면 되겠습니다.

점화식의 일종이라고 생각하면 되지 않을까 싶네요 :)

profile
하루 하루 즐겁게

0개의 댓글