문제
어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.
예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.
문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.
접근법
일단 문제 조건이
"number는 2자리 이상, 1,000,000자리 이하인 숫자입니다"
라고 되어있는데 대충 보면 number<=10^6이니까 널널하지 않을까? 생각했는데 잘 보면 '자리'라는거...
k는 1이상 number의 자리 미만이니까 최대 10^6-1 자리까지 나올 수 있음
1914 / k=2를 예로 들어보면
십의 자리 수 - 1 9 1 중에서 고를 수 있음(일의 자리를 구해야 하기 때문에 4는 고를 수 없음)
일의 자리 수 - 십의 자리 수에서 고른 수 바로 뒤 ~ 4 중에서 고를 수 있음(십의 자리에서 고른 수 앞은 구할 수 없음)
본인들이 고를 수 있는 범위에서 가장 큰 수를 골라서 모으면 그게 가장 큰 숫자가 됨 (94)
- 각 숫자가 고를 수 있는 범위를 구해서, 그 중 가장 큰 수를 구한 뒤 해당 index+1이 다음 숫자가 고를 수 있는 범위의 시작 index가 됨
- 끝 index의 경우에는 k부터 시작해서, +1씩 해주면 됨
예시
"1231234" / k=3 일 때 4자리의 숫자를 구해야 되기 때문에
천의 자리 - 0 - 3(===k) 번째 자리에서 구할 수 있음 - 3(index는 2) 선택
백의 자리 - 3 - 4 번째 자리에서 구할 수 있음 - 2(index는 4) 선택
십의 자리 - 5 - 5 번째 - 3(index는 5) 선택
일의 자리 - 6 - 6 번째 - 4 선택
코드
function solution(number, k) {
number = number.split("").map(Number)
const {length} = number
const 몇자리 = length-k //return값의 자리 수
let result = ''
let [start,end] = [0,k]
for(let i=0;i<몇자리;i++){
let stack = [[number[start],start]]
for(let j=start+1;j<=end;j++){
if(stack.at(-1)[0] < number[j]){
stack.shift()
stack.push([number[j],j])
}
if(number[j] === 9){break}
}
result += stack.at(-1)[0]
start = stack.at(-1)[1] + 1
end ++
}
return result
}
- start,end로 범위 나타내기
- 스택(은 아니긴 하지만)을 이용해서 해당 범위에서 가장 큰 수와 그 index를 구해서 다음 start,end 바꿔주기
- 여기서 number를 배열로 바꿔주고, 9에 대한 예외처리를 안해주면 10번만 통과 못함
'JS' 카테고리의 다른 글
프로그래머스 - 보석 쇼핑 JS (0) | 2023.07.17 |
---|---|
프로그래머스 - 인사고과 JS (0) | 2023.07.13 |
프로그래머스 - 셔틀버스 JS (0) | 2023.06.30 |
다크모드 감지해서 적용하는 법 (0) | 2023.06.09 |
비동기 2탄 - Promise (0) | 2023.03.22 |