두 정수 X, Y의 임의의 자리에서 공통으로 나타나는 정수 k(0 ≤ k ≤ 9)들을 이용하여 만들 수 있는 가장 큰 정수를 두 수의 짝꿍이라 합니다(단, 공통으로 나타나는 정수 중 서로 짝지을 수 있는 숫자만 사용합니다). X, Y의 짝꿍이 존재하지 않으면, 짝꿍은 -1입니다. X, Y의 짝꿍이 0으로만 구성되어 있다면, 짝꿍은 0입니다.
예를 들어, X = 3403이고 Y = 13203이라면, X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 3, 0, 3으로 만들 수 있는 가장 큰 정수인 330입니다. 다른 예시로 X = 5525이고 Y = 1255이면 X와 Y의 짝꿍은 X와 Y에서 공통으로 나타나는 2, 5, 5로 만들 수 있는 가장 큰 정수인 552입니다(X에는 5가 3개, Y에는 5가 2개 나타나므로 남는 5 한 개는 짝 지을 수 없습니다.)
두 정수 X, Y가 주어졌을 때, X, Y의 짝꿍을 return하는 solution 함수를 완성해주세요.
3 ≤ X, Y의 길이(자릿수) ≤ 3,000,000입니다.
X, Y는 0으로 시작하지 않습니다.
X, Y의 짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.
X | Y | result |
---|---|---|
"100" | "2345" | "-1" |
"100" | "203045" | "0" |
"100" | "123450" | "10" |
"12321" | "42531" | "321" |
"5525" | "1255" | "552" |
입출력 예 #1
X, Y의 짝꿍은 존재하지 않습니다. 따라서 "-1"을 return합니다.
입출력 예 #2
X, Y의 공통된 숫자는 0으로만 구성되어 있기 때문에, 두 수의 짝꿍은 정수 0입니다. 따라서 "0"을 return합니다.
입출력 예 #3
X, Y의 짝꿍은 10이므로, "10"을 return합니다.
입출력 예 #4
X, Y의 짝꿍은 321입니다. 따라서 "321"을 return합니다.
입출력 예 #5
지문에 설명된 예시와 같습니다.
function solution(X, Y) {
let arrX = new Map();
let arrY = new Map();
let common = new Map();
for(let i = 0; i< X.length; i++){
arrX.set(X[i], (arrX.get(X[i])||0) + 1);
}
for(let i = 0; i< Y.length; i++){
arrY.set(Y[i], (arrY.get(Y[i])||0) + 1);
}
for(let [kX,vX] of arrX)
for(let[kY,vY] of arrY){
if(kX === kY){
common.set(kX, vX <= vY ? arrX.get(kX) : arrY.get(kY))
}
}
let str = '';
if(common.size === 0)
str = '-1';
else if([...common].filter(([k,v]) => k != 0).length === 0)
str = '0';
else{
for(let [k,v] of [...common].sort((a,b) => b[0] - a[0])){
str += k.repeat(v)
}
}
return str;
}
각 X와 Y를 map()
에 넣어서 자릿수의 갯수를 세 줬다. 그리고 자릿수의 갯수를 비교한 다음 작은 쪽의 값을 새로운 map()
에 넣어 주었다.
그리고 배열이 비었다면 -1을, 전체가 0으로 구성되어있으면 0을, 아니라면 값을 비교하여 큰 순서대로 문자를 합쳐주었다.
const solution = (x, y) => {
let result = '';
const map = new Map();
for(let i = 0; i < y.length; i++){
map.set(y[i], (map.get(y[i]) || 0) + 1);
}
for(let i = 0; i < x.length; i++){
if(map.get(x[i]) >= 1){
map.set(x[i], (map.get(x[i]) || 0) -1)
result += x[i];
}
}
if(result.length < 1) return '-1';
return +result === 0 ? '0' : result.split('').sort((a, b) => b - a).join('');
}
사실 중복되는 부분이 많아서 고민이 많았는데, 중복을 없앤 깔끔한 풀이인 듯 하다. 나는 X와 Y의 각 숫자의 갯수를 다른 map()
에 넣어줬는데, 이 풀이에서는 한 개의 map()
에 넣어주었다. 처음에 Y의 각 자릿수의 갯수를 센 다음, X의 자릿수의 갯수를 세는데 key값이 하나라도 있으면 비교하는 곳으로 넘어간다. 거기서 숫자를 세 주는데, 이번에는 존재한다면 값을 -1씩 빼주고 key값을 result에 더해 준다.
그래서 빈 배열이라면 -1을 인출한다. 값 전체가 0인 경우는 문자 배열 앞에 +를 넣어 숫자로 형변환 해준 후에 0이면 0을 리턴, 아니라면 문자를 나눈 다음에 정렬해서 다시 문자로 돌려 준다.
function solution(X, Y) {
let common = new Map();
let arrY = [...Y]
let arrX = [...X]
for(let i = 0 ; i< arrX.length; i++){
for(let j = 0; j< arrY.length; j++){
if(arrX[i] === arrY[j]){
common.set(arrX[i], (common.get(arrX[i])||0) + 1);
arrX.splice(i,1);
arrY.splice(j,1);
i--;
j--;
break;
}
}
}
let str = '';
if(common.size === 0)
str = '-1';
else if([...common].filter(([k,v]) => k != 0).length === 0)
str = '0';
else{
for(let [k,v] of [...common].sort((a,b) => b[0] - a[0])){
str += k.repeat(v)
}
}
return str;
}
function solution(X, Y) {
let arrX = [...X]
let arrY = [...Y]
let common = [];
for(let i = 0; i< arrX.length; i++)
for(let j = 0; j < arrY.length; j++){
if(arrX[i] === arrY[j]){
common.push(arrX[i]);
arrX.splice(i,1);
arrY.splice(j,1);
i--;
j--;
break;
}
}
if(common.length === 0)
return '-1'
else if(common.filter(v => v != 0).length === 0)
return '0'
else
return common.sort((a,b) => b-a).join('');
}
아무리 break를 걸고 map에 넣어준다고 해도 splice()
와 push()
가 들어가는 이상 시간 초과가 난다. 들어올 값이 큰 경우에는 이 함수들을 사용하는 것을 자제해야겠다.