정수로 이루어진 배열 numbers
가 있습니다. 배열 의 각 원소들에 대해 자신보다 뒤에 있는 숫자 중에서 자신보다 크면서 가장 가까이 있는 수를 뒷 큰수라고 합니다.
정수 배열 numbers
가 매개변수로 주어질 때, 모든 원소에 대한 뒷 큰수들을 차례로 담은 배열을 return 하도록 solution 함수를 완성해주세요. 단, 뒷 큰수가 존재하지 않는 원소는 -1을 담습니다.
numbers
의 길이 ≤ 1,000,000numbers[i]
≤ 1,000,000numbers | result |
---|---|
[2, 3, 3, 5] | [3, 5, 5, -1] |
[9, 1, 5, 3, 6, 2] | [-1, 5, 6, 6, -1, -1] |
2의 뒷 큰수는 3입니다. 첫 번째 3의 뒷 큰수는 5입니다. 두 번째 3 또한 마찬가지입니다. 5는 뒷 큰수가 없으므로 -1입니다. 위 수들을 차례대로 배열에 담으면 [3, 5, 5, -1]이 됩니다.
9는 뒷 큰수가 없으므로 -1입니다. 1의 뒷 큰수는 5이며, 5와 3의 뒷 큰수는 6입니다. 6과 2는 뒷 큰수가 없으므로 -1입니다. 위 수들을 차례대로 배열에 담으면 [-1, 5, 6, 6, -1, -1]이 됩니다.
처음에는 단순하게 numbers
의 값을 하나씩 고정시켜두고, 뒤에 있는 값 중에 현재 값 보다 큰 값이 있다면 result
배열에 push, 없다면 -1
을 push하는 방식으로 풀었다.
하지만 시간초과가 발생헀고 다른 방법을 찾아야 했다.
function solution(numbers) {
let result = [];
for (let i = 0; i < numbers.length; i++) {
let val = numbers[i];
let check = false;
for (let j = i + 1; j < numbers.length; j++) {
if (val < numbers[j]) {
result.push(numbers[j]);
check = true;
break;
}
}
if (!check) result.push(-1);
}
return result;
}
시간 복잡도를 줄이기 위해 for문을 하나 줄여야 했다.
따라서 아래와 같이 수정을 했다.
numbers
의 길이만큼 배열을 생성하여 값을 모두 -1
로 채우기stack
을 생성하고, for문을 돌며 index 값을 pushstack
에 값이 있고, 현재 위치 이전의 값 중 현재 값보다 작은 값이 있다면 stack
에서 꺼내서 그 값을 현재 값으로 변경전체 코드는 아래와 같다.
function solution(numbers) {
let result = new Array(numbers.length).fill(-1)
let stack = []
// 현재 값을 기준으로
// 앞에 있는 값 중에서 값이 정해지지 않고, 현재 값보다 작은 값 바꾸기
for (let i=0; i<numbers.length; i++) {
// 값이 변경되지 않은 인덱스가 있고, 현재 값보다 인덱스에 해당하는 값이 작은 경우
while (stack && numbers[stack[stack.length-1]] < numbers[i]) {
result[stack.pop()] = numbers[i]
}
// (값이 변경되지 않은) 현재 index push
stack.push(i)
}
return result;
}
정말 이런 코드를 다들 어떻게 작성하는지 모르겠다.
알고리즘 역량은 아직 경험해야 할 게 많다고 느꼈다.