프로그래머스 - 가장 큰 수 (Javascript)

문제 설명

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”

풀이 과정

처음에 조금 삽질을 했다…
그냥 sort 함수에서 정방향으로 더한 것과 치환하여 더한 것을 비교만 해주면 되는 문제였는데.. 너무 생각이 많았던 것 같다.

  1. string 두 개를 붙여준 뒤 해당 값의 대소비교를 해줘야 하기 때문에 stringArr를 만들었다.

    numbers.map(num ⇒ num.toString())

  2. 이제 string으로 변환된 stringArrsort()를 활용해 정렬해준다.

  3. sortFunction의 원리는 간단하다. 정방향과 치환된 문자열 두 개를 서로 비교해준 뒤, 더 큰 값이 앞으로 정렬되도록 하면 되기 때문이다.

javascript Array.prototype.sort()의 동작원리를 이해해보자

사실 위의 풀이 방법은 자바스크립트 내장 메소드인 sort() 동작 원리를 이해해야 쉽게 이해하고 풀이할 수 있다

1
2
3
4
5
const array = [20, 100, 50, 30];

array.sort((a, b) => a - b); // 오름차순 정렬 => [20, 30, 50, 100]

array.sort((a, b) => b - a); // 내림차순 정렬 => [100, 50, 30, 20]

근데 왜 b-a가 내림차순이 되는걸까?
sort()ab의 연산 후 반환값이 음수면 자리를 바꾸고, 양수면 그대로 둔다는 특성을 갖는다.
이를 이해하고 아래의 정렬 과정을 보면 이해가 쉬울 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 차례대로 확인해보자! [20,100,50,30]

// 그리고 헷갈릴 수도 있는데, sort 함수에서는 a가 뒷 요소, b가 앞 요소를 가리킨다.

// 1. 20(b) - 100(a) === 음수(-) -> [100,20,50,30] // 음수니까 자리 바꿈
// 2. 20(b) - 50(a) === 음수(-) -> [100,50,20,30] // 상동
// 3. 20(b) - 30(a) === 음수(-) -> [100,50,30,20] // 상동

// 그럼 이런 경우는 어떨까? [100,50,70,200]

// 1. 100 - 50 === 양수 (+) -> [100, 50, 70, 200]
// 2. 50 - 70 === 음수(-) -> [100, 70, 50, 200]
// 3. 50 - 200 === 음수(-) -> [100, 70, 200, 50]
// ... 이 과정이 반복!

이처럼, return값이 양수면 그대로 위치를 유지하고, 음수면 자리를 바꿔준다는 로직만 이해하고 있으면 된다.

따라서 a-b, b-a일 경우에는 대소비교에 따라 음수 양수 값이 정반대가 되기 때문에 b-a일 때에는 내림차순 정렬이, a-b일 때에는 오름차순 정렬이 되는 것이다.


소스코드 (첫 시도… 대실패)

너무 생각이 많았다. 그냥 대소비교를 해주면 될 것을… 뭔가 숨겨진 공식이 있을 것 같아서 머리를 굴리다가 외려 좋지 못한 코드가 나왔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function solution(numbers) {
let answer = '';
const stringArr = numbers.map((num) => num.toString());
const sortedArr = stringArr.sort((a, b) => {
if (b[0] !== a[0]) return Number(b[0]) - Number(a[0]);
if (b.length === a.length) return Number(b) - Number(a);
// 앞에가 긴 놈일 때
if (a.length > b.length) {
// 앞 자리가 끝 자리보다 클 때
if (Number(a[0]) > Number(a[a.length - 1])) {
return Number(a) - Number(b);
}
// 앞 자리가 끝 자리보다 작을 때
return Number(b) - Number(a);
}
// 뒤에가 긴 놈일 때
if (b.length > a.length) {
// 앞 자리가 끝 자리보다 클 때
if (Number(b[0]) > Number(b[b.length - 1])) {
return Number(b) - Number(a);
}
// 앞 자리가 끝 자리보다 작을 때
return Number(a) - Number(b);
}
return 0;
});
sortedArr.forEach((arr) => (answer += arr));
return answer;
}

소스코드 (최종)

그냥 욕심을 버리고 다시 처음부터 생각해봤다.
그냥 간단하게 대소비교만 해주면 된다는 생각에 아래와 같이 간단하게 풀어낼 수 있었다.

1
2
3
4
5
6
7
8
function solution(numbers) {
let answer = '';
const stringArr = numbers.map((num) => num.toString());
stringArr.sort((a, b) => Number(b + a) - Number(a + b));
if (stringArr[0] === '0') return '0';
answer = stringArr.join('');
return answer;
}

프로그래머스 - 가장 큰 수 (Javascript)

https://hoonjoo-park.github.io/algorithm/programmers/largestNumber/

Author

Hoonjoo

Posted on

2022-03-27

Updated on

2022-03-27

Licensed under

Comments