[Java] 정수 내림차순으로 배치하기 (programmers)

Haeun Noh·2023년 1월 14일
0

programmers

목록 보기
31/64
post-thumbnail

0114


문제 설명

함수 solution은 정수 n을 매개변수로 입력받습니다. n의 각 자릿수를 큰것부터 작은 순으로 정렬한 새로운 정수를 리턴해주세요. 예를들어 n118372873211을 리턴하면 됩니다.


제한 조건

n1이상 8000000000 이하인 자연수입니다.


입출력 예

nreturn
118372873211

소스 코드

class Solution {
    public long solution(long n) {
        
        String[] an = Long.toString(n).split("");// long을 String으로
        int[] num = new int[an.length];// 실제 정답 담을 배열
        
        for ( int i = 0; i < an.length; i++)
            num[i] = Integer.parseInt(an[i]);
        
        // 내림차순 정렬
        for ( int i = 0; i < num.length; i++) {
            for ( int j = 1; j < num.length-i; j++ ) {
                if ( num[j-1] < num[j] ) {
                    int tmp = num[j-1];
                    num[j-1] = num[j];
                    num[j] = tmp;
                }
            }
        }
        
        String str = "";
        for (int i = 0; i < num.length; i++)
            str += Integer.toString(num[i]);
        
        return Long.parseLong(str);
    }
    
    // 테스트를 위한 코드
    public static void main(String[] args) {
        Solution ri = new Solution();
        System.out.println(ri.solution(118372));
    }
}

소스 풀이

    public long solution(long n) {
        
        String[] an = Long.toString(n).split("");// long을 String으로
        int[] num = new int[an.length];// 실제 정답 담을 배열

longString으로 형 변환을 시켜 각각의 정수를 나누어 배열에 담기 위해 String배열의 an을 선언한다.
문자열 배열을 사용한 이유는 split을 사용하기 위함이다.
long타입인nlong.toString()으로 문자열로 바꾼 뒤 split("")으로 한 자리씩 떼어놓아 an의 각 방에 저장한다.

내림차순 정렬을 하기 위해서 '수' 비교가 필요하기 때문에 이를 위한 num배열을 선언한다.


        for ( int i = 0; i < an.length; i++)
            num[i] = Integer.parseInt(an[i]);

큰 수와 작은 수를 비교하여 내림차순 정렬을 할 것이기 때문에 an[i]의 값을 Integer.parseInt()를 이용해 int -> String으로 모두 변환을 시켜 num배열에 저장한다.


        // 내림차순 정렬
        for ( int i = 0; i < num.length; i++) {
            for ( int j = 1; j < num.length-i; j++ ) {
                if ( num[j-1] < num[j] ) {
                    int tmp = num[j-1];
                    num[j-1] = num[j];
                    num[j] = tmp;
                }
            }
        }

첫 번째 for문은 수 비교를 마친 뒤 한 바퀴를 돌게 된다.
이해가 안 된다면 그냥 두 번째 for문에서 비교가 일어난다고 이해하자.

두 번째 for문에서는 수의 비교가 일어난다.
j의 초기값이 1인 이유는 j-1을 해야하기 때문이다. 전의 수와 이후의 수를 비교해야 하는데 j=0이라면 overflow에러가 나게 된다. j-10-1이 되며 num[-1]이 될 수도 있기 때문이다.
jnum.length-i의 직전일 때까지 for문이 반복되는데 왜 i를 빼는 것일까? 사실 i를 빼지 않아도 결과의 차이는 없다. 다만 if문의 조건상 제일 작은 수가 맨 뒤로 가게 될 것이고 이 작은 수는 앞으로의 for문반복에서도 바뀌지 않을 것이다. 이 때 i를 빼지 않으면 불필요한 연산을 계속 하게 될 것이므로 i만큼을 빼줌으로서 실행 시간을 조금이나마 줄이는 것이다.
if문이다. 앞의 수가 커야 하고, 뒤의 수가 작아야 한다. 따라서 앞의 수인 num[j-1]num[j]보다 커야하는데 만약 num[j-1num[j]보다 작다면 두 수의 위치를 바꾸어 작은 수가 뒤로 가도록 한다.


        String str = "";
        for (int i = 0; i < num.length; i++)
            str += Integer.toString(num[i]);
        
        return Long.parseLong(str);

return할 문자열 str""로 초기화시킨다.

num.length만큼 for문을 반복하며 num[i]Integer.toString()으로 문자열로 만든 뒤 str에 더한다. 여기서 문자열의 더한다는 의미는 연산의 의미가 아니라 붙인다는 의미임을 기억하자.

답인 str를 다시 Long.parseLong()을 이용해 문자열 -> long으로 형변환을 시킨 뒤 return한다. 여기서 long으로 다시 형변환을 하는 것은 solution의 리턴타입이 long이기 때문이다.


실행 결과



profile
기록의 힘을 믿는 개발자, 노하은입니다!

0개의 댓글