728x90
조건
정수로 이루어진 배열 numbers가 있습니다. 배열 의 각 원소들에 대해 자신보다 뒤에 있는 숫자 중에서 자신보다 크면서 가장 가까이 있는 수를 뒷 큰수라고 합니다.
정수 배열 numbers가 매개변수로 주어질 때, 모든 원소에 대한 뒷 큰수들을 차례로 담은 배열을 return 하도록 solution 함수를 완성해주세요. 단, 뒷 큰수가 존재하지 않는 원소는 -1을 담습니다.
제한조건
- 4 ≤ numbers의 길이 ≤ 1,000,000
- 1 ≤ numbers[i] ≤ 1,000,000
입출력 예
| numbers | result |
| [2, 3, 3, 5] | [3, 5, 5, -1] |
| [9, 1, 5, 3, 6, 2] | [-1, 5, 6, 6, -1, -1] |
알고리즘 예상
- 간단하게 slice와 first를 이용해서 해결할 수 있을 것 같다.
- 단 numbers의 길이가 1000000까지 갈 수 있으므로 시간복잡도에 대해서 생각을 해봐야한다.
초기 코드
class Solution {
fun solution(numbers: IntArray): IntArray {
var answer: IntArray = intArrayOf()
return answer
}
}
내 코드
// 테스트 케이스 통과, 실패(시간 초과)
class Solution {
fun solution(numbers: IntArray): IntArray {
val answer: IntArray = IntArray(numbers.size) { 0 }
for (i in numbers.indices){
val number = numbers.slice(i..numbers.lastIndex).filter { it > numbers[i] }
answer[i] = if (number.isEmpty()) -1 else number[0]
}
return answer
}
}
역시 예상대로 시간초과가 떴다. 다른방법을 이용해봐야겠다.
//성공
import java.util.Stack
class Solution {
fun solution(numbers: IntArray): IntArray {
val answer: IntArray = IntArray(numbers.size) { -1 }
val numbersWithIndex = numbers.mapIndexed { i, c -> i to c }.toTypedArray()
val stack = Stack<Pair<Int, Int>>()
for (i in numbersWithIndex) {
if (stack.isEmpty()) stack.push(i)
else {
var peek = stack.peek()
while (peek.second < i.second) {
answer[peek.first] = i.second
stack.pop()
if (stack.isEmpty()) break
peek = stack.peek()
}
stack.push(i)
}
}
return answer
}
}
원래 풀이가 매 원소마다 배열의 끝까지 반복했기 때문에 느렸던 것이라고 생각해 Stack을 이용해 한바퀴만 돌리는 것으로 바꿔보았다.index를 사용할 필요가 있어 map을 이용해 인덱스를 포함해 스택에 넣어주었다.
다른 사람의 풀이
import java.util.*
class Solution {
fun solution(numbers: IntArray): IntArray {
val answer = mutableListOf<Int>()
val s = Stack<Int>()
for(i in numbers.lastIndex downTo 0) {
var bigNum = -1
while(s.isNotEmpty()){
if(s.peek() > numbers[i]) {
bigNum = s.peek()
break
}
else { s.pop() }
}
answer.add(bigNum)
s.push(numbers[i])
}
return answer.reversed().toIntArray()
}
}
class Solution {
fun solution(numbers: IntArray): IntArray {
val n = numbers.size
val answer = IntArray(n) { 0 }
answer[n - 1] = -1
for (i in n - 2 downTo 0) {
when {
numbers[i + 1] == numbers[i] -> answer[i] = answer[i + 1]
numbers[i + 1] > numbers[i] -> answer[i] = i + 1
else -> {
var index = i + 1
while (index >= 0 && numbers[index] <= numbers[i])
index = answer[index]
answer[i] = index
}
}
}
return answer.map { if (it == -1) -1 else numbers[it] }.toIntArray()
}
}
개선점 또는 배운점
- 대부분 스택을 이용해서 풀었다.
- 아래 풀이는 피보나치 수열문제를 풀 때처럼 DP방식을 이용해 해결했다.
728x90
'TIL > 알고리즘' 카테고리의 다른 글
| 07/17 알고리즘 공부 - 글자 이어 붙여 문자열 만들기 (0) | 2024.07.17 |
|---|---|
| 07/15 알고리즘 공부 - 주사위게임 (3) (0) | 2024.07.15 |
| 04/22 알고리즘 공부(97) - 모음 사전 (0) | 2024.04.22 |
| 04/19 알고리즘 공부(96) - 주차 요금 계산 (0) | 2024.04.19 |
| 04/18 알고리즘 공부(95) - k진수에서 소수 개수 구하기 (0) | 2024.04.18 |