티스토리 뷰
문제
원본 사이트 : programmers.co.kr/learn/courses/30/lessons/42746?language=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 |
풀이
1. sort() 메서드의 compareFunction을 직접 만들어 비교 - (실패)
function solution(numbers) {
var answer = '';
numbers.sort((a, b) => {
const stringA = a.toString().replace(/(0+$)/, "");
const stringB = b.toString().replace(/(0+$)/, "");
if(stringA == stringB){
return a - b;
}
else{
if(stringA > stringB) return -1;
else if(stringA < stringB) return 1;
else return 0;
}
});
for(let i=0; i<numbers.length; i++){
answer += numbers[i];
}
return answer.replace(/(^0+)/, "0");
}
- numbers.sort() : 두 수를 비교해 내림차순으로 정렬
- stringA, stringB : a, b를 각각 string으로 변환한 뒤, 문자열 끝에 나오는 '0'을 모두 제거
- stringA와 stringB가 같으면 숫자로 비교해 작은 숫자를 더 앞에 오도록 sort (a: 1, b: 10인 경우 a가 더 큰 숫자가 될 수 있도록)
- stringA와 stringB가 같지 않은 경우에는 string 값으로 비교해 내림차순 정렬((stringB - stringA)을 return 하게 되면 숫자로 인식해서 틀린 결과가 나오므로 if문으로 비교)
- for문을 돌며 numbers의 값들을 answer에 붙이기
- 0만 있는 경우, answer 값이 0...0이 되므로 문자열의 첫번째에 반복해서 나오는 0...0을 0으로 replace
→ 이렇게 하면 테스트 케이스와 내가 추가한 몇 개의 테스트 케이스는 모두 통과하는데, 실제로 코드를 제출하면 7개의 케이스에서 '실패'하게 됨
2. String으로 변환한 뒤, 두 개의 합으로 순서 지정 - (+13)
function solution(numbers) {
var answer = numbers.map((number) => number.toString()).sort((a, b) => (b+a) - (a+b)).join("");
return answer.replace(/^0+/, "0");
}
- map() 메서드를 통해 numbers의 요소들을 모두 string으로 변형
- string으로 변형한 numbers를 sort() 메서드를 통해 정렬
- a+b와 b+a로 비교해 내림차순으로 정렬
- join() 메서드를 통해 배열의 모든 요소를 문자열로 이어붙임
- 0만 있는 경우, answer 값이 0...0이 되므로 문자열의 첫번째에 반복해서 나오는 0...0을 0으로 replace해서 결과 return
정렬할 때, 단순히 a와 b로만 비교하는 게 아니라 a+b와 b+a로 비교하면 문자열로 바꿨기 때문에 숫자의 합이 아닌, 문자열의 합을 가지고 비교하게 된다.
예를 들어 a=1과 b=10을 비교할 경우, (a+b)는 11이 아닌 110이 되고, (b+a)는 101이 된다.
이 두 문자열을 비교해 더 큰게 앞에 오도록 (b+a) - (a+b)를 return해준다.
후기
이 문제는 두 문자열을 이어서 비교하는 (b+a) - (a+b)가 핵심이다.
이 방법만 잘 생각이 나면 코드는 두줄로 끝이 나는데, 어렵게 생각하면 계속 꼬이게 되고 시간만 낭비하게 되는 그런 문제였다.
결국 처음 시도하던 방법을 포기하고 구글링을 통해 (b+a) - (a+b)를 깨닫게 되었지만, 이런 방법이 있다는 것을 알게 된 게 중요하다고 생각한다.
앞으로 이걸 종종 써먹어야지...
그리고 프로그래머스 문제를 풀수록 map()이나 filter(), sort() 등의 메서드들을 많이 쓰게 되어서 사용법을 익힐 수 있어서 좋은 것 같다.
'알고리즘 > Programmers' 카테고리의 다른 글
[Programmers] 코딩테스트 연습: 2020 KAKAO BLIND RECRUITMENT - 문자열 압축 (javascript) 문제 풀이 (0) | 2020.09.28 |
---|---|
[Programmers] 정렬: Level 2 - H-Index (javascript) 문제 풀이 (0) | 2020.09.11 |
[Programmers] 정렬: Level 1 - K번째수 (javascript) 문제 풀이 (0) | 2020.09.10 |
[Programmers] 해시: Level 3 - 베스트앨범 (javascript) 문제 풀이 (0) | 2020.09.08 |
[Programmers] 해시: Level 2 - 위장 (javascript) 문제 풀이 (0) | 2020.09.07 |
- Total
- Today
- Yesterday
- 하이퍼레저 페브릭
- Hyperledger Fabric v1.2
- Hyperledger Fabric
- 알고리즘
- Hyperledger Fabric v1.1
- 코딜리티
- 문제풀이
- Blockchain
- 빅데이터 강의
- javascript
- 하이퍼레저 패브릭
- Hyperledger Indy
- 직딩잇템
- 기초 of 기초 데이터 개념
- DOCs
- codility
- 블록 체인
- 빅데이터 교육
- docker
- 어서와 데이터는 처음이지
- 하이퍼레저 인디
- 코딩테스트
- Private Data
- 암브로셔스
- ubuntu
- 빅데이터 기초
- 빅데이터
- 코테
- ambrosus
- 블록체인
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 30 |