알고리즘 공부

99클럽 코테 스터디 11일차 TIL

HD9504 2024. 8. 1. 21:35

오늘의 학습 키워드

  • 정렬 (Sorting)
  • 문자열 조작 (String Manipulation)

문제

프로그래머스 가장 큰 수 문제

문제 이해

주어진 숫자 배열에서 각 숫자를 조합하여 만들 수 있는 가장 큰 수를 구하는 문제입니다. 숫자들은 정수 형태로 주어지며, 이를 문자열로 변환하여 가장 큰 수를 만들 수 있도록 정렬해야 합니다.

실패한 풀이

public class Main {
    public static void main(String[] args) {
        int[] numbers = new int[]{3, 2, 7, 2};
        System.out.println(solution(numbers));
    }

    public static String solution(int[] numbers) {
        StringBuilder sb = new StringBuilder();
        Integer[] newArray = Arrays.stream(numbers).boxed().toArray(Integer[]::new);
        Arrays.sort(newArray, (x, y) -> {
            String strX = String.valueOf(x);
            String strY = String.valueOf(y);
            String lastX = String.valueOf(strX.charAt(strX.length() - 1));
            String lastY = String.valueOf(strY.charAt(strY.length() - 1));
            String concatX = strX.concat(lastX.repeat(4 - strX.length()));
            String concatY = strY.concat(lastY.repeat(4 - strY.length()));
            int compareX = Integer.parseInt(concatX);
            int compareY = Integer.parseInt(concatY);
            if(compareY == compareX){
                return strX.length() - strY.length(); // 오름차순
            }
            return  compareY - compareX; //내림차순
        });

        for (int i = 0; i < newArray.length; i++) {
            if(i == 0 && newArray[i] == 0){
                return "0";
            }
            sb.append(newArray[i]);
        }
        return sb.toString();
    }
}

실패한 이유

  • 이 풀이는 숫자를 문자열로 변환한 후 마지막 숫자를 반복하여 비교하는 방식으로 정렬했습니다. 하지만 이 방법은 숫자들이 실제로 조합될 때의 크기 비교를 제대로 반영하지 못합니다. 결과적으로, 올바른 순서를 찾지 못해 최대 숫자를 정확하게 도출하지 못했습니다.

정답 풀이

import java.util.*;

class Solution {
    public String solution(int[] numbers) {
        String[] strNumbers = Arrays.stream(numbers)
                                    .mapToObj(String::valueOf)
                                    .toArray(String[]::new);

        Arrays.sort(strNumbers, (x, y) -> (y + x).compareTo(x + y));

        if (strNumbers[0].equals("0")) {
            return "0";
        }

        StringBuilder sb = new StringBuilder();
        for (String str : strNumbers) {
            sb.append(str);
        }

        return sb.toString();
    }
}

풀이 설명

  1. 숫자 배열을 문자열 배열로 변환
    • Arrays.stream(numbers)로 숫자 배열을 스트림으로 변환하고, mapToObj(String::valueOf)를 통해 각 숫자를 문자열로 변환한 후 배열로 변환합니다.
  2. 정렬
    • 문자열을 정렬할 때 (y + x)(x + y)를 비교합니다. 예를 들어, 숫자 330이 있을 때, 330303을 비교하여 더 큰 값을 선택합니다. 이를 통해 최종적으로 큰 수가 앞에 오도록 정렬합니다.
  3. 예외 처리
    • 가장 큰 값이 0인 경우(예: [0, 0, 0]) 결과는 "0"이어야 하므로, 첫 번째 요소가 "0"이면 "0"을 반환합니다.
  4. 결과 조합
    • 정렬된 문자열을 순서대로 합쳐서 최종 결과를 도출합니다.

오늘의 회고

  • 이 문제는 숫자를 어떻게 정렬할지에 대한 문제로, 문자열 조합의 크기를 비교하는 방법이 핵심이었습니다. 처음에는 문자열을 길이와 끝자리로 비교하려고 했지만, 이는 올바른 방법이 아니었습니다.
  • 최종적으로 정답 풀이에서는 두 숫자를 이어붙였을 때의 크기를 비교하여 정렬하는 방법을 사용하여 올바른 답을 구할 수 있었습니다.
  • 이 문제를 통해 문자열 정렬과 비교에 대한 이해를 더욱 깊이 할 수 있었으며, 각종 문자열 조작을 통해 더 큰 수를 찾는 로직을 익힐 수 있었습니다.