Notice
Recent Posts
Recent Comments
Link
관리 메뉴

윤일무이

[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 가장 큰 수 본문

⚙️ 코딩테스트

[JavaScript] 프로그래머스 코딩테스트 레벨 2 : 가장 큰 수

썸머몽 2023. 6. 27. 01:47
728x90

📌  문제

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"

📌  풀이

알아야 하는 것

  • arr.map()
  • arr.join()
  • arr.filter

구할 것

  • sort를 어떤 식으로 할 것인지?

1-1. 사전식 정렬

[10, 2, 6] [3, 30, 34, 5, 9]가 나와서 reverse를 하면 되는 줄 알았다.

[6, 2, 10]로 1번째 TC는 맞지만 [9, 5, 34, 30, 3]으로 2번째 TC는 30과 3의 위치가 바뀌지 않았다. 

 

오기로 이렇게 10, 100, 1000으로 나눠 떨어지는 경우라면 그 원소를 삭제하고 추가하는 방식으로 진행해보았으나 당연히 실패했다.

   if (nums[i] % 10 === 0) {
      let num = nums[i];
      nums.splice(i, 1);
      nums.push(num);
    }

애초에 이렇게 정렬하는 게 잘못된 접근인가? 하는 생각이 들었다.

예컨대 [10, 10, 1000]이 들어왔을 때 사전식 정렬+reverse를 하면 [1000, 10, 10]으로 원래 나와야 할 [10101000]이 나오지 않기 때문이었다. 3가지 TC에서 상이한 답이 나오는 걸 보면 너무 좁은 시야로 보고 있는 것 같아 다른 방식으로 정렬하기로 했다.

 

1-2. 문자열로 변환 후 정렬

내림차순을 하든 오름차순을 하든 사전식 정렬을 하든 0이 들어간 숫자가 걸리게 된다.

문제에서 문자열로 반환하라고 하기도 하고, 실제로 수를 만들 때도 숫자+숫자로 연산을 하는 게 아니라 문자+문자로 연산을 한다. 따라서 먼저 주어진 배열을 문자열 배열로 바꿔주고, 정렬을 다시 해봤다.

 let nums = numbers.map((v) => String(v)).sort((a, b) => b + a - (a + b));
 // 문자열로 배열 재생성 후 내림차순

예컨대 ['3', '30', '34', '5', '9'] 가 있으면 '3'+'30' 이랑 '30'+'3' 이랑 비교해서 더 큰 수대로 정렬했다.

그러면 330이랑 303으로 330이 더 커서 3, 30 순으로 정렬해 우선 원하는 반환값 모양을 반쯤 갖출 수 있게 된다.

 

이후 '3'+'34'와 '34'+'3'으로 34가 3보다 앞으로 오고... 이런 식으로 34330 처럼 계속 비교해 나가면 된다.

정렬을 이런 식으로 할 수도 있다, 계속 새로운 방향으로 생각해야 한다.

 

2. 결과값 반환

정렬한 후 문자열 배열로 있는 값을 join 메소드로 묶어 하나의 배열로 만든다.

그런데 이 때 문자열이기 때문에 ['0', '0', '0']의 경우 '000'으로 묶이는 요상한 결과가 발생한다.

이런 수는 없기 때문에 '0'만 나오게 해야 한다.

 

따라서 배열의 길이 === 0의 개수와 같다면 배열의 요소 전체가 0인 셈이니 "00", "000" 같은 결과라면 "0"만 나올 수 있도록 조건문을 하나 달아주고, 조건문에 해당되지 않으면 (전원 0이 아니면) 원래대로 답을 반환할 수 있게끔 코드를 작성했다.

 

function solution(numbers) {
  let nums = numbers.map((v) => String(v)).sort((a, b) => b + a - (a + b));
  let answer = nums.join("");
  let countZero = nums.filter((e) => "0" === e).length;

  if (answer.length === countZero) {
    return "0";
  } else {
    return answer;
  }
}

 

정렬하는 방법을 틀에 갇혀 생각하지 말고 구현하고자 하는 방식대로 고쳐 나가보자...

728x90