결국 친구의 도움으로 해결했다 ㅜㅜ 갈길이 먼 코린이의 하루..
큰 수 만들기
문제 설명
어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.
예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.
문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.제한 조건
- number는 1자리 이상, 1,000,000자리 이하인 숫자입니다.
- k는 1 이상 number의 자릿수 미만인 자연수입니다.
입출력 예
number k return 1924 2 94 1231234 3 3234 4177252841 4 775841
function solution(number, k){
var answer = ''
var length = number.length - k
for(let i=0; i<number.length;){
var pointer = number[i]
if(answer.length = length){ // k개만큼 빼면
break; // 반복문 나가기
}
if(pointer == 9){ // number에 들어올 수 있는 제일 큰 숫자
answer += pointer.toString()
i++
continue // 밑에 짜놓은 코드는 무시하도록
}
var bigNum = biggerNumber(number, i)
if(bigNum.val == -1){ // number중에 제일 큰 수면
answer += pointer.toString()
i++
} else {
// pointer ~ bigNum있는 곳까지의 length 크기
var pointer_len = bigNum.idx - i
// 그 사이의 거리(length)가 k보다 작으면
if(pointer_len <= k){
k = k - pointer_len // k 줄이기
i = bigNum.idx // i는 bigNum의 인덱스가 됨
} else { // k랑 같거나 크면
answer += pointer.toString()
i++
}
}
}
return answer
}
// number와 해당 pointer의 인덱스를 매개변수로 받는 함수 만들어줌
function biggerNumber(number, pointerIndex){
let value, idx = 0
for(let i = pointerIndex; i<number.length; i++){
/* 처음이 아닌 "pointer가 있는 곳"부터 ~ number의 끝까지 돌아야 하므로
pointerIndex로 시작해야 한다.
그렇지 않으면 number의 뒤쪽에 위치한 수가 앞쪽의 위치한 수랑 일치할 때
애먼 값으로 계산해버릴 수 있기 때문이다. */
if(number[i]>number[pointerIndex]){
value = number[i]
idx = i
break // pointer ~ number끝까지 중 pointer보다 큰 "제일 첫번째 수"
} else {
value = -1 // pointer가 제일 크면 -1을 반환
}
}
return {val: value, idx: idx}
}
- 우선 입출력 예시와 같이 만약 number = 4177252841 이 들어온다면
- 맨 첫 원소 4를 pointer로 잡는다.
- number를 돌며 pointer보다 큰 수가 있는지 파악한다.
3-1. 주의: 순서대로 돌면서 만나는 pointer보다 큰 첫번째 수여야 한다.
3-2. 7이 4보다 크고, 4가 만나는 첫번째 큰 수이다.- pointer부터 7까지 그 사이에 몇 개의 원소가 있는지 확인한다.
4-1. 4, 1이 있으므로 총 두개이다.
4-2. 이는 곧 7의 index에서 pointer의 index를 뺀 값과 동일하다. (2-0 = 2)- 그 사이에 있는 원소 개수가 k보다 작으면, 그 원소들은 제외시켜도 되는 수들이다.
5-1. pointer를 해당 큰 수의 인덱스로 바꾼다.- 그 사이에 있는 원소 개수가 k보다 크면, 더이상 원소를 제외시킬 수 없다.
6-1. 현재 pointer는 뺄 수 없는 수이므로 answer에 합친다.- answer의 길이가 number의 길이에서 k를 뺀 값이 될 때까지 반복한다.
E1. 만약 number에 9999999999 가 들어온다면
1-1. 9를 일일이 다 돌면 시간초과가 된다. 따라서 9의 경우 어차피 뺄 수 없는 제일 큰 수라는 것을 인지하고 answer에 합친다.
알고리즘은 틀리지 않았지만, 구현에 많은 시간이 들었다.
우선, pointer보다 큰 첫번쨰 수를 구하는 부분에서 어려움을 겪었다. 단순하게 find() 함수를 사용했는데, 그렇게 하다보니 number의 처음부터 끝까지 중 가장 첫번째로 등장하는 큰 수를 반환하였다.
나는... pointer 앞에 있는 애들 말고 뒤에 있는 애들을 찾아야 하는데 ...
또한, (아직 코린이라 그런지) for문에서 i++을 안써줘도 되는지 몰랐다.
어쩔땐 i++이 되도록, 어쩔땐 i = bigNum이 되도록 다르게 짜도 되대..? 허허
마지막으로, continue에 대한 복습을 할 수 있었다. 9가 들어오면 굳이 bigNum을 찾는 과정은 생략하고 빠르게 answer에 넣어준 후 다음 인덱스로 가야 하는데 continue를 빼먹어서 또 실패했었다.
그 외에도 사실 조급한 마음이나 실패에 대한 내부귀인을 일삼는 요즘 나의 바람직하지 못한 마음가짐 때문에 더 더뎌진 것도 있다.. 이제 시작한 코린이가 급히 실력을 쌓고 싶어 안절부절하는지 모르겠다. 코린이라는 걸 명심하고, 멋진 코른이는 긴 호흡으로 꾸준히 이어가야 될 수 있다는 것을 계속해서 인지하자 !! 성장하고 있는 느낌이 팍팍 들지 않는다고 (부디 제발) 의미없는 자책은 하지 말기를 !