Level 2 ) 뒤에 있는 큰 수 찾기 ⭐️

Doozuu·2023년 11월 19일
0

프로그래머스 (JS)

목록 보기
172/183

문제 설명

정수로 이루어진 배열 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]

입출력 예 설명

입출력 예 #1
2의 뒷 큰수는 3입니다. 첫 번째 3의 뒷 큰수는 5입니다. 두 번째 3 또한 마찬가지입니다. 5는 뒷 큰수가 없으므로 -1입니다. 위 수들을 차례대로 배열에 담으면 [3, 5, 5, -1]이 됩니다.

입출력 예 #2
9는 뒷 큰수가 없으므로 -1입니다. 1의 뒷 큰수는 5이며, 5와 3의 뒷 큰수는 6입니다. 6과 2는 뒷 큰수가 없으므로 -1입니다. 위 수들을 차례대로 배열에 담으면 [-1, 5, 6, 6, -1, -1]이 됩니다.


풀이

순서대로 순회하며 가장 가까운 큰 수를 찾아 push하는 풀이
시간 복잡도 N*2으로 시간초과로 인해 4개의 테스트 케이스에서 틀리게 된다.

function solution(numbers) {
    let answer = [];
    
    function findNum(val, idx){
        for(let j=idx+1;j<numbers.length;j++){
            if(numbers[j] > val) return numbers[j];
        }
        return -1;
    }
    
    for(let i=0;i<numbers.length;i++){
        let cur = numbers[i];
        answer.push(findNum(cur,i));
    }
    
    return answer;
}

개선된 풀이

뒤에서 부터 찾기

  • 최댓값보다 현재값이 같거나 크면 : 최댓값 갱신, 조회 배열을 최댓값으로 초기화
  • 최댓값보다 현재값이 작으면 : 조회 배열 탐색
    • 조회 배열 맨 앞에 있는 값이 현재값 보다 크면 해당 값을 정답 배열에 추가, 현재값을 조회 배열에 추가
    • 조회 배열 맨 앞에 있는 값이 현재값 보다 같거나 작으면 해당 값을 제거

예제 ) [9, 1, 5, 3, 6, 2]

i = 5
maxnum = 2
answer = [-1]
stack = [2]

i = 4
maxnum = 6
answer = [-1, -1]
stack = [6]

i = 3
maxnum = 6
answer = [-1, -1, 6]
stack = [3, 6]

i = 2
maxnum = 6
5 > 3
stack = [6]
5 < 6
answer = [-1, -1, 6, 6]
stack = [5, 6]

i = 1
maxnum = 6
1 < 5
answer = [-1, -1, 6, 6, 5]
stack = [1, 5, 6]

i = 0
maxnum =  9
answer = [-1, -1, 6, 6, 5, -1]
stack = [9]
function solution(numbers) {
    let answer = [];
    let max = 0;
    let search_arr = [];
    
    for(let i=numbers.length-1;i>=0;i--){
        if(numbers[i] >= max){
            max = numbers[i];
            answer.push(-1);
            search_arr = [numbers[i]];
        }else{
            while(1){
                if(numbers[i] < search_arr[0]){
                    answer.push(search_arr[0]);
                    search_arr.unshift(numbers[i]);
                    break;
                }else{
                    search_arr.shift();
                }
            }
        }
    }
    
    return answer.reverse()
}
profile
모든게 새롭고 재밌는 프론트엔드 새싹

0개의 댓글