Programmers - 정렬 > 가장 큰 수

내 풀이

처음에 생각한 알고리즘은 굉장히 복잡하였다.

  1. 맨 앞자리끼리 비교해서 내림차순으로 정렬한다.
  2. 맨 앞자리가 같은 요소 중 글자길이가 작은 것을 앞에 정렬한다.(생각해보면 이 것부터 틀렸다. 50보다 588이 앞에 들어가야한다.)

해당 방법으로 진행하려 했지만 알고리즘 자체가 너무 복잡했고 런타임 에러가 뜰 것이 분명했기에 다른 방법을 고민하였다.

array에 sort api를 조작하는 것

sort api에 대하여

sort api를 살펴보면 return 값이 0 또는 양수이면 그대로, 음수이면 자리를 뒤바꾸는 작업을 한다.
예를 들면 조금 더 쉽게 이해된다.

array = [4, 2, 3, 5, 1]
array.sort((a, b) => a - b)

sort api에서 신박한 점은 처음 argument로 a, b를 받아올 때 a = 2, b = 4를 가리킨다는 점이다. (b가 0번째 요소, a가 1번째 요소를 가리킨다.)

즉 a - b는 2 - 4를 뜻하고 음수를 return 하기 때문에 4, 2의 자리는 뒤바뀌게 된다. 따라서 array는 오름차순으로 정렬되게 되는 것이다.

function solution(numbers) {
  if(numbers.every((number) => number == 0)){
    return '0';
  }
  let answer = numbers.sort((a, b) => {
    if (Number(String(a) + String(b)) < Number(String(b) + String(a))) {
      return 1;
    }
    if (Number(String(a) + String(b)) > Number(String(b) + String(a))) {
      return -1;
    }
    return 0;
  });
  answer = answer.join("");
  return answer;
}

먼저 numbers에 [6, 10, 2]가 들어왔다고 가정해보자.

전체 정렬이 6210이 되려면 두 원소를 그대로 합치고 뒤집어서 합쳤을 때 큰 값이 앞에 정렬되게끔 해야 한다. ( 106 보다는 610이 더 크기 때문에 6, 10으로 정렬되야 한다.)

먼저 parameter a에는 10이, b에는 6이 들어가는 경우를 살펴보자.

106 < 610 이면 return 값으로 양수를 반환하여 정렬을 그대로 둔다.

이번에는 a에 2가 b에 10이 들어가는 경우를 살펴보자.

210 > 102 이면 return 값으로 음수를 반환하여 두 값의 자리를 바꾼다.

따라서 6, 2, 10 으로 정렬이 마무리된다.


numbers의 모든 원소의 값이 0일 경우 string으로 0을 return 하는 case를 만든다.

모범 답안

딱 봐도 간단해보인다. 내 코드랑 다른 점을 확인해보자.

  • 형변환을 사용하는 대신에 백틱을 사용하여 string을 표현하였다.
  • .sort().join() 체이닝을 사용해 결과값을 바로 문자열로 변환하였다.
  • numbers의 모든 원소가 0인 경우 sort 이후 answer의 첫번째 원소에도 0이 들어가있기 때문에 해당 case에는 '0'을 return 하고, 그 외의 경우에는 answer를 그대로 return 한다. (이 부분은 정말 감탄스럽다...)
function solution(numbers) {
  let answer = numbers.sort((a, b) => `${b}${a}` - `${a}${b}`).join('');
  return answer[0] === '0' ? '0' : answer;
}

얻어갈 부분

알고리즘을 처음 블로그에 게시해봤는데 쓰면서 좀 더 깊게 고민하게되고 더 잘 받아들여지는 것 같다.

체이닝을 사용하는 것에 익숙해져야겠다.

내가 고민하는 알고리즘이 너무 복잡하다면 빠르게 다른 방법을 시도해보는 용기가 필요하다.

좋은 웹페이지 즐겨찾기