ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] - 가장 큰 수 (42746) (정렬/ Comparator/ stream)
    알고리즘/프로그래머스 2024. 3. 21. 11:22

    📚 문제 - 42746

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

    예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다. 0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.


    제한사항

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

    입출력 예

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

     

     

    ⌨️ 작성한 코드

    import java.util.Arrays;
    import java.util.Comparator;
    
    class Solution {
        public String solution(int[] numbers) {
            // 정렬을 위해 String 배열로 변환
            String[] nums = new String[numbers.length];
            
            for (int i = 0; i < numbers.length; i++) {
                nums[i] = String.valueOf(numbers[i]);
            }
            
            // 두 문자열을 합쳐 비교 후, 내림차순으로 정렬
            Arrays.sort(nums, new Comparator<String>() {
                @Override
                public int compare(String a, String b) {
                    return (b + a).compareTo(a + b);
                }
            });
            
            // 모든 숫자가 0일 경우 처리
            if (nums[0].equals("0")) {
                return "0";
            }
            
            // 정렬된 문자열 붙이기
            StringBuilder sb = new StringBuilder();
            for (String num : nums) {
                sb.append(num);
            }
            
            return sb.toString();
        }
    }
    • 접근 방식:
      숫자를 String으로 변환한 뒤, 두 문자열을 합쳐서 크기 비교를 하면 될 것 같았다. 그래서 Comparator를 사용해서 내림차순으로 정렬했고, StringBuilder로 빠르게 합쳐서 문자열로 return했다.

    • 문제&해결:
      모든 숫자가 0인 경우를 처리 안해줘서 처음에 계속 틀렸었다. 문제를 다시 천천히 읽어보니 numbers의 원소는 0이상이므로 0이 포함되어있었다. 그래서 정렬 후, 첫번째가 0이면 모든 수가 0인 것이므로 "0"이 return되도록 해서 해결했다.

    • 최적화:
      String배열로 변환할 때, java8의 스트림을 사용하는 편이 더 보편적인 방식인 것 같아서 코드를 수정했다. 조금이지만 속도도 좀 더 빨라졌다. 찾아보니 스트림을 사용하면 내부적으로 병렬 처리가 가능하여 대량의 데이터를 다룰 때 더 빠를 수 있다고 한다.
      // 정렬을 위해 String 배열로 변환
      String[] strings = Arrays.stream(numbers) // int 배열을 IntStream으로 변환
                              .mapToObj(String::valueOf) // int를 String으로 변환
                              .toArray(String[]::new); // 문자열 배열로 변환


    ✅ 배운 점

    [ Java 8의 스트림 (stream) ]

    Stream: 컬렉션을 다루는 더 유연하고 강력한 방법을 제공한다.

     

    주요 메소드:

    • filter(Predicate<T> predicate): 주어진 조건을 만족하는 요소만을 포함하는 스트림을 반환
    • map(Function<T, R> mapper):각 요소를 주어진 함수에 매핑하여 새로운 요소로 이루어진 스트림을 반환
    • forEach(Consumer<T> action):각 요소에 대해 주어진 동작을 수행
    • collect(Collector<T, A, R> collector):스트림의 요소를 수집하여 결과를 반환
    • skip(long n):처음 n개의 요소를 제외한 스트림을 반환
    • findFirst():스트림의 첫 번째 요소를 반환
    • sorted():스트림의 요소를 정렬
    • distinct():스트림의 중복 요소를 제거
      // 활용 예시
      import java.util.Arrays;
      
      public class Main {
          public static void main(String[] args) {
              // 숫자 리스트
              Integer[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
              
              // 짝수를 걸러내고 제곱값을 구하여 콘솔에 출력
              Arrays.stream(numbers)
                    .filter(n -> n % 2 == 0)       // 짝수만 걸러냄
                    .map(n -> n * n)               // 제곱값 계산
                    .forEach(System.out::println); // 각 값을 콘솔에 출력
          }
      }​

     

     

Designed by Tistory.