[stack] 프로그래머스Lv2-주식가격

초록귤·2025년 9월 13일
0

JS코테

목록 보기
12/12

주식가격

문제 설명
초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어질 때, 가격이 떨어지지 않은 기간은 몇 초인지를 return 하도록 solution 함수를 완성하세요.
제한사항
prices의 각 가격은 1 이상 10,000 이하인 자연수입니다.
prices의 길이는 2 이상 100,000 이하입니다.
입출력 예
prices return
[1, 2, 3, 2, 3][4, 3, 1, 1, 0]
입출력 예 설명
1초 시점의 ₩1은 끝까지 가격이 떨어지지 않았습니다.
2초 시점의 ₩2은 끝까지 가격이 떨어지지 않았습니다.
3초 시점의 ₩3은 1초뒤에 가격이 떨어집니다. 따라서 1초간 가격이 떨어지지 않은 것으로 봅니다.
4초 시점의 ₩2은 1초간 가격이 떨어지지 않았습니다.
5초 시점의 ₩3은 0초간 가격이 떨어지지 않았습니다.

1.제일 기억할 풀이 - stack

function solution(prices) {
  const answer = new Array(prices.length).fill(0);
  const stack = [];
  let length = prices.length;

  for(let i = 0; i < length; i++) {
    while(stack.length && prices[i] < prices[stack[stack.length - 1]]) {
      let temp = stack.pop();
      answer[temp] = i - temp;
    }
    stack.push(i);
    console.log(stack,'stack')
  }

  while(stack.length) {
    let temp = stack.pop();
    console.log(`temp:${temp} =>${length-temp - 1}`)
    answer[temp] = length - temp - 1;
  }

  return answer;
}
// 스택활용(2)
function solution(prices) {
   const n=prices.length
   const answer = new Array(n).fill(0);
   const stack =[]; // [인덱스, 가격] 저장
    
   for (let i=0; i<n; i++){
       // 현재 가격보다 높은 이전 가격들 처리
       while (stack.length >0 && stack[stack.length-1][1] >prices[i]){
           console.log(stack[stack.length-1][1],'stack[stack.length-1][1]')
           console.log(stack[0][1],'stack[0][1]')
           console.log(prices[i],'prices[i]')
           const [prevIndex, prevPrice] = stack.pop();
           
           answer[prevIndex] = i-prevIndex
       }
       stack.push([i,prices[i]]) // 인덱스,값
       console.log(stack)
   }
    // 스택에 남은 항목들 처리 (끝까지 떨어지지 않은 경우)
    while (stack.length > 0) {
        const [index, price] = stack.pop();
        answer[index] = n-1-index;
    }
    console.log(answer,'answer')
    return answer;
}

기억할것

스택 = 아직 가격이 떨어지지 않은 시점들
for문 = 실시간으로 가격 하락 감지
마지막 while문 = 끝까지 안 떨어진 것들 정리

2.구현

function solution(prices) {
   return prices.map((currentPrice,i) => {
       let count = 0;
       // 현재 시점부터 끝까지 확인
       for (let j=i+1; j<prices.length; j++){
           count++;
           // 가격이 떨어지면 즉시 종료
           if (currentPrice > prices[j]){
               break;
           }
       }
       return count;
   })
}

3.처음풀이

function solution(prices) {
    const answer =[]
    prices.forEach((currentPrice,i)=> {
        let notFallTime = 1;
        for(let index =i+1; index<prices.length; index++){
           if(index===prices.length-1){return answer.push(notFallTime)}
           if(currentPrice <= prices[index]){
              notFallTime++
           }
           else{return answer.push(notFallTime)}
        }
    })
    answer.push(0)
    return answer;
}

3번 보충-forEach: 별도의 콜백함수 스코프

이유: forEach의 콜백은 독립적인 함수이므로 return이 그 콜백만 종료

// for문: 같은 함수 스코프 내
function test1() {
    for(let i = 0; i < 3; i++) {
        if(i === 1) return "함수 종료"; // 전체 함수 종료
    }
    return "완료"; // 실행되지 않음
}

// forEach: 별도의 콜백 함수 스코프
function test2() {
    [0,1,2].forEach(i => {
        if(i === 1) return; // 콜백만 종료
    });
    return "완료"; // 실행됨! ✅
}

각 상황에서 return의 의미

상황별 올바른 제어

// ❌ forEach에서 전체 중단 시도
arr.forEach(item => {
    if(condition) return; // 현재만 skip, 전체는 계속
});

// ✅ 전체 중단이 필요하면
// 방법 1: for...of 사용
for(const item of arr) {
    if(condition) break; // 전체 중단
}

// 방법 2: some() 사용  
arr.some(item => {
    if(condition) return true; // 전체 중단
    return false; // 계속
});

// 방법 3: try-catch (비추천)
try {
    arr.forEach(item => {
        if(condition) throw new Error();
    });
} catch(e) {}

forEacn -> return 대신 continue

profile
초록색 귤이 노랑색으로 익어가듯, 실력이 익어가기 위해 노력하는 개발자 초록귤입니다.

0개의 댓글