본문 바로가기
카테고리 없음

[정렬] 가장 큰 수

by yeaseul912 2022. 4. 18.
728x90

1.  문제 설명

더보기

0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.

예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.

0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.

2. 제한사항

더보기
  • numbers의 길이는 1 이상 100,000 이하입니다.
  • numbers의 원소는 0 이상 1,000 이하입니다.
  • 정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.

3. 입출력예

numbers return
[6, 10, 2] "6210"
[3, 30, 34, 5, 9] "9534330"

4. 풀이 과정

Solution 1 ( 실패 ) 
  1. 숫자 배열을 문자 배열로 변환
  2. 문자열 비교하여  큰 수 부터 정렬
  3. 하나의 문자열로 합쳐서 반환

단순하게 " 문자로 만들어서 큰 것 부터 나열하면 되지 않을까? " 라고 생각했는데 엉뚱한 결과가 나왔다.

 public String solution(int[] numbers) {
        String[] inputV = new String[numbers.length];
        
        for(int i=0; i<numbers.length; i++){
            inputV[i] = String.valueOf(numbers[i]);
        } 
        
        return compare(inputV);
    }
    
    public String compare(String[] inputV){
        
    for(int i = 0; i<inputV.length-1; i++) {
        for(int j = i+1; j<inputV.length; j++){
            String now = inputV[i];
            String next = inputV[j];
            int compareV = now.compareTo(next);
            if(compareV > 0) {
                inputV[i] = now;
                inputV[j] = next;
            } else{
                inputV[i] = next;
                inputV[j] = now;
            }
        }
    }
        
        return String.join("",inputV);
    }

두번째 입력 값에 대하여 9 > 5 > 34 > 30 > 3 으로 계산이 되었다. ( 문자만 비교했을 땐 그게 맞긴 하네.)

 

Solution2 ( 실패 )
  1. 숫자 배열을 문자 배열로 변환
  2. 두 문자열 더한 것을 비교하여 큰 수 부터 정렬( ex, [30, 3] => (330 > 303) => [3, 30] )
  3. 하나의 문자열로 합쳐서 반환

compareV 를 변경해 주었더니 예제는 통과했다. (테스트는 통과하지 못했다. )

// int compareV = now.compareTo(next);
int compareV = (now+next).compareTo(next+now);

 

 

Solution3 ( 성공 )

 1. 시간초과 : 조건문을 개선한다. ( bubble sort -> java library 사용 )

 2. 테스트 11 실패 : [0, 0, 0] 배열이 들어와서 답이 "000" 인 경우  => "0"으로 반환

public String solution(int[] numbers) {
    String[] inputV = new String[numbers.length];

    for(int i=0; i<numbers.length; i++){
        inputV[i] = String.valueOf(numbers[i]);
    } 

    // 라이브러리를 사용하여 비교 및 정렬 끝!
    Arrays.sort(inputV, new Comparator<String>(){
        public int compare(String s1, String s2){
            return (s2+s1).compareTo(s1+s2);
        }
    });
    
    String answer = "";
    for(String s : inputV) answer += s;
  
   // 0 일 경우 
    if(inputV[0].equals("0")) return "0";


    return String.join("",inputV);
}

 

 

Solution4 (Solution3 리팩토링)

 

 - 자바 8 람다 함수 사용

    Comparator 객체는 메서드가 하나 뿐인 함수형 인터페이스를 구현하기 때문에 람다 함수로 대체가 가능.

// 라이브러리를 사용하여 비교 및 정렬 끝!
Arrays.sort(inputV, new Comparator<String>(){
    public int compare(String s1, String s2){
        return (s2+s1).compareTo(s1+s2);
    }
});

=>

Arrays.sort(inputV, (s1, s2) -> {
    return (s2+s1).compareTo(s1+s2);
});

 

 

- static method를 사용하여 문자열 배열을 문자열로 변환 ( java8 릴리스에 추가 )

String answer = "";
for(String s : inputV) answer += s;

=>

String answer = String.join("",inputV);

 

 

- 권장되는 문자열 비교 방법

if(inputV[0].equals("0")) return "0";

=>

if(answer.startsWith("0")) return "0";

 

 

- 최종 코드

public String solution(int[] numbers) {
   String[] inputV = new String[numbers.length];
   
   // 숫자 배열을 문자 배열로 변환
    for(int i=0; i<numbers.length; i++){
        inputV[i] = String.valueOf(numbers[i]);
    }
    
    // 내림차순으로 정렬
    Arrays.sort(inputV, (s1, s2) -> {
        return (s2+s1).compareTo(s1+s2);
    });

    // 문자열 조합 및 예외 처리
    String answer = String.join("",inputV);
    if(answer.startsWith("0")) return "0";

    return answer;
}

 

 

 

Solution5 ( Solution4 리팩토링 )

 - JAVA Stream 사용

import java.util.stream.*;

public String solution(int[] numbers) {
    String answer = IntStream.of(numbers)
    //  .mapToObj(n -> String.valueOf(n)) // static method 사용 권장
        .mapToObj(String::valueOf) //method reference 로 축약 가능
        .sorted((s1, s2) -> (s2+s1).compareTo(s1+s2))
        .collect(Collectors.joining());

    if(answer.startsWith("0")) return "0";

    return answer;
}

 

5. 결과 

 Solution2

Solution 3

Solution 4

Solution 5

6. 마치며

뭔가 결과를 보면서 어떤게 시간이 제일 적게 걸리는지 보는것도 재밌어서 채점 결과까지 올리게된다. ㅎㅅㅎ

java 8 부터 뭔가 많이 생긴것같다. Stream은 정말 유용하면서도 너무 생소하다.

빨리 친해지도록 노력해야지.!

반응형

댓글