문제 설명
초 단위로 기록된 주식가격이 담긴 배열 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초간 가격이 떨어지지 않았습니다.
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문 = 끝까지 안 떨어진 것들 정리
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;
})
}
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;
}
이유: 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 "완료"; // 실행됨! ✅
}
// ❌ 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