본문 바로가기
알고리즘

프로그래머스 - 코딩테스트 고득점 kit - 정렬 - 가장 큰 수 / javascript

by 자유코딩 2020. 7. 19.

프로그래머스 코딩테스트 고득점 kit 의 정렬 - 가장 큰 수를 풀었다.

 

답은 이렇다.

 

function solution(numbers) {
  const arr = numbers.map((n) => n + '') // 문자열로 바꾸기
    .sort((a, b) => (b + a) - (a + b)) // 조합한 숫자들을 내림차순으로 정렬
  // a 가 뒤에있는 숫자, b가 앞에 있는 숫자
  return arr[0] === '0' ? '0' : arr.join(''); // 배열의 모든 요소가 0인경우 처리
}
// 배열에서 만들어 낼 수 있는 가장 큰 수
// [6,10,2] => 6210
const result = solution([9, 90, 534, 52, 910]);

console.log(result);

 

답이 왜 그런지 하나씩 살펴본다.

 

일단 sort 함수는 arr.sort((a,b) => a-b) 하면 오름차순 정렬이 된다.

내림차순을 하려면 arr.sort((a,b) => b-a) 이런식으로 하면 된다.

 

처음엔 sort 함수를 구현해서 100의자리, 10의 자리, 1의자리 쪼개서 하려고 했었다. 그랬더니 코드가 130줄이 넘어갔고. 결정적으로 틀렸었다.

 

이 방법은 문자열을 앞에서부터 조합하면서 정렬한다.

 

먼저 map 을 하면

numbers.map((n) => n + '')
// [6,10,2] 배열이 ['6','10','2']로 바뀐다.

 

그리고 이 문자열을 앞에서부터 조합하면서 내림차순으로 정렬한다.

 

 .sort((a, b) => (b + a) - (a + b)) // 조합한 숫자들을 내림차순으로 정렬

이 부분을 살펴보기 위해서 console.log 를 해봤다.

const arr = numbers.map((n) => n + '') // 문자열로 바꾸기
    .sort((a, b) => {
      console.log(`a ${a}`);
      console.log(`b ${b}`);
      console.log(`a + b ${a + b}`);
      console.log(`b + a ${b + a}`);
    })

배열이 [6,10,2]일때 이 코드는 아래와 같이 출력한다.

첫번째에서 a 를 10으로 출력했다.

b가 6이다.

즉 b가 앞에 있는 숫자고 a가 뒤에 있는 숫자를 의미한다.

a+b는 106이 되었다.

b+a는 610이 되었다.

 

이 둘을 만약에 오름차순으로 하고 싶다면 

(a+b) - (b+a)로 sort 에 적으면 될 것이다.

 

아까 a,b 두개만 있을때 내림차순은 b-a였다.

 

여기서도 내림차순을 하고 싶다면 (b+a) - (a+b)를 하면 더한 값의 내림차순으로 정렬될 것이다.

 

첫번째 단계에서는 106보다 610이 더 크니까 6,10,2 의 배열에서 6,10 을 그대로 둔다.

 

두번째 단계에서는 102와 210을 비교한다. 210이 더 크니까 10과 2의 순서를 바꾼다.

6,2,10 이 된다.

 

이런 식으로 더 큰수의 조합을 만드는 순서대로 내림차순 정렬한다.

 

그리고 arr.join('')을 해서 하나의 문자열로 만든다.

 

마지막으로 배열에 숫자가 0으로만 구성된 경우를 예외처리 해준다.

return arr[0] === '0' ? '0' : arr.join('');

내림차순의 첫번째 문자열은 가장 큰 문자열이다.

그런데 그게 0이라는 말은 전부 다 0이라는 말이다.

 

그럴때는 0을 리턴한다.

아니면 arr.join('')해서 문자열을 리턴한다.

댓글