스택/큐

(1) 기능개발: 코플릿 박스 포장과 매우 유사한 문제이나, 여기서는 배열을 직접 구해야 한다.

function solution(progresses, speeds) {
    const answer = [];

    //남은 일자에 대한 배열 완성하기 [7,3,9] .map써도 된다. 
    const daysLeft = [];
    progresses.forEach((el,index) => {
        daysLeft.push(Math.ceil((100 - el) / speeds[index]))
    })

    //
    while(daysLeft.length){
        //daysLeft 배열의 특정 요소 이후에 , 특정 요소보다 작은 게 몇개인지 확인
        let idx = daysLeft.findIndex(el => el > daysLeft[0]);
        if(idx === -1){
            answer.push(daysLeft.length);
            daysLeft.splice(0,daysLeft.length)
        }else{
            answer.push(idx);
            daysLeft.splice(0,idx);
        }
    }
    return answer;
}

(2) 주식가격

function sol(prices){
  /*
  해당 요소 이후의 숫자들 중, 해당 요소보다 작은 숫자 찾기. 
  그것을 배열에 축적하기
  */
  const answer = [];
  //해당 요소 이후의 숫자들 중에 해당 요소보다 작은게 하나도 없다: answer 배열에 , 배열의 길이-1 푸시한다. 
  //그리고 해당 요소는 shift해서 버린다. 
  //해당 요소 이후의 숫자들 중에, 해당 요소보다 작은 게 있다. 처음으로 작은 숫자가 나온 인덱스를 구한다.
  //그러면 그 인덱스를 answer 배열에 집어넣는다.
  //해당 요소는 shift해서 버린다. 
  //위 과정을 주어진 배열이 모두 사라질 때까지 반복한다. 
  while(prices.length){
    let idx = prices.findIndex(el => prices[0] > el);
    if(idx === -1){
      answer.push(prices.length - 1);
      prices.shift();
    }else{
      answer.push(idx);
      prices.shift();
    }
  }
  return answer;
}

console.log(sol([1,2,3,2,3])); //[4,3,1,1,0]

또 다른 방법
let answer = [];
  while(prices.length){
    const temp = prices.shift();
    const idx = prices.findIndex(el => el < temp);
    if(idx === -1){
      answer.push(prices.length)
    }else{
      answer.push(idx + 1)
    }
  }
  return answer;

(3) 프린터

function solution(priorities, location) {
  /*
  예시 이해하기
  [2,1,3,2]의 경우, location 2: 3은 몇번째로 인쇄되니??
  2를 대기 목록에서 꺼낸다: 2 [1,3,2]
  나머지 [1,3,2]에서 2보다 큰 수가 존재하니, 2를 가장 마지막에 넣는다.: [1,3,2,2]

  1을 대기 목록에서 꺼낸다: 1 [3,2,2]
  나머지 [3,2,2]에서 1보다 큰 수가 존재하니, 1를 가장 마지막에 넣는다.: [3,2,2,1]

  3을 대기 목록에서 꺼낸다: 3 [2,2,1]
  나머지 [2,2,1]에서 3보다 큰 수가 없다, 3을 인쇄한다 [2,2,1] -1번째 인쇄 ** 여기서 !

  2를 대기 목록에서 꺼낸다: 2 [2,1]
  나머지 [2,1]에서 2보다 큰 수가 없다, 2를 인쇄한다.: [2,1] - 2번째 인쇄

  2를 대기 목록에서 꺼낸다: 2 [1]
  나머지 [1]에서 2보다 큰 수가 없다, 2를 인쇄한다.: [1] - 3번째 인쇄

  1를 대기 목록에서 꺼낸다: 1 []
  나머지 []에서 1보다 큰 수가 없다, 1를 인쇄한다.: [] - 4번째 인쇄
  */
  /*
  예시 이해하기 2
  [1,1,9,1,1,1]의 경우 : location 0 : "맨앞의"1은 몇번째로 인쇄되니?
  1을 대기목록에서 꺼낸다 1 [1,9,1,1,1]
  나머지 [1,9,1,1,1]에서 1보다 큰 수가 존재하니, 1을 가장 마지막에 넣는다.: [1,9,1,1,1,1*]

  1을 대기목록에서 꺼낸다 1 [9,1,1,1,1]
  나머지 [9,1,1,1,1]에서 1보다 큰 수가 존재하니, 1을 가장 마지막에 넣는다.: [9,1,1,1,1*,1]

  9을 대기목록에서 꺼낸다 9 [1,1,1,1,1]
  나머지 [1,1,1,1,1]에서 9보다 큰 수가 없다, 9을 인쇄한다.: [1,1,1,1*,1] - 1번째 인쇄

  1을 대기목록에서 꺼낸다 1 [1,1,1,1]
  나머지 [1,1,1,1]에서 1보다 큰 수가 없다, 1을 인쇄한다.: [1,1,1*,1] - 2번째 인쇄

  1을 대기목록에서 꺼낸다 1 [1,1,1]
  나머지 [1,1,1]에서 1보다 큰 수가 없다, 1을 인쇄한다.: [1,1*,1] - 3번째 인쇄

  1을 대기목록에서 꺼낸다 1 [1,1]
  나머지 [1,1]에서 1보다 큰 수가 없다, 1을 인쇄한다.: [1*,1] - 4번째 인쇄

  1을 대기목록에서 꺼낸다 1 [1]
  나머지 [1]에서 1보다 큰 수가 없다, 1*을 인쇄한다.: [1] - 5번째 인쇄 : 여기!

  1를 대기 목록에서 꺼낸다: 1 []
  나머지 []에서 1보다 큰 수가 없다, 1를 인쇄한다.: [] -6번째 인쇄

  */

  /*
  예시 이해하기 3
  [1,9,11,1,2,8]의 경우 : location 3 : 세번째 1은 몇번째로 인쇄되니? [0,1,2,3,4,5]
  1을 대기목록에서 꺼낸다 1 [9,11,1,2,8]
  나머지 [9,11,1,2,8]에서 1보다 큰 수가 존재하니, 1을 가장 마지막에 넣는다.: [9,11,1*,2,8,1] [1,2,3,4,5,0]

  9을 대기목록에서 꺼낸다 9 [11,1*,2,8,1]
  나머지 [11,1*,2,8,1]에서 9보다 큰 수가 존재하니, 9을 가장 마지막에 넣는다.: [11,1*,2,8,1,9] [2,3,4,5,0,1]

  11을 대기목록에서 꺼낸다 11 [1*,2,8,1,9]
  나머지 [1*,2,8,1,9]에서 11보다 큰 수가 없다, 11을 인쇄한다.: [1*,2,8,1,9] - 1번째 인쇄 [3,4,5,0,1]

  1*을 대기목록에서 꺼낸다 1* [2,8,1,9] 
  나머지 [2,8,1,9]에서 1*보다 큰 수가 있다, 1*을 가장 마지막에 넣는다: [2,8,1,9,1*] [4,5,0,1,3]

  2을 대기목록에서 꺼낸다 2 [8,1,9,1*]
  나머지 [8,1,9,1*]에서 2보다 큰 수가 있다, 2을 가장 마지막에 넣는다: [8,1,9,1*,2] [5,0,1,3,4]

  8을 대기목록에서 꺼낸다 8 [1,9,1*,2]
  나머지 [1,9,1*,2]에서 8보다 큰 수가 있다, 8을 가장 마지막에 넣는다: [1,9,1*,2,8] [0,1,3,4,5]

  1을 대기목록에서 꺼낸다 1 [9,1*,2,8]
  나머지 [9,1*,2,8]에서 1보다 큰 수가 있다, 1을 가장 마지막에 넣는다: [9,1*,2,8,1] [1,3,4,5,0]

  9를 대기 목록에서 꺼낸다: 9 [1*,2,8,1]
  나머지 [1*,2,8,1]에서 9보다 큰 수가 없다, 9를 인쇄한다: [1*,2,8,1] - 2번째 인쇄 [3,4,5,0]

  1*을 대기목록에서 꺼낸다 1* [2,8,1]
  나머지 [2,8,1]에서 1*보다 큰 수가 있다, 1*을 가장 마지막에 넣는다: [2,8,1,1*] [4,5,0,3]

  2을 대기목록에서 꺼낸다 2 [8,1,1*]
  나머지 [8,1,1*]에서 2보다 큰 수가 있다, 2을 가장 마지막에 넣는다: [8,1,1*,2] [5,0,3,4]

  8를 대기 목록에서 꺼낸다: 8 [1,1*,2]
  나머지 [1,1*,2]에서 8보다 큰 수가 없다, 8를 인쇄한다: [1,1*,2] - 3번째 인쇄 [0,3,4]

  1을 대기목록에서 꺼낸다 1 [1*,2]
  나머지 [1*,2]에서 1보다 큰 수가 있다, 1을 가장 마지막에 넣는다: [1*,2,1] [3,4,0]

  1*을 대기목록에서 꺼낸다 1* [2,1]
  나머지 [2,1]에서 1*보다 큰 수가 있다, 1*을 가장 마지막에 넣는다: [2,1,1*] [4,0,3]

  2를 대기 목록에서 꺼낸다: 2 [1,1*]
  나머지 [1,1*]에서 2보다 큰 수가 없다, 2를 인쇄한다: [1,1*] - 4번째 인쇄 [0,3]

  1를 대기 목록에서 꺼낸다: 1 [1*]
  나머지 [1*]에서 1보다 큰 수가 없다, 1를 인쇄한다: [1*] - 5번째 인쇄 [3]

  1*를 대기 목록에서 꺼낸다: 1* []
  나머지 []에서 1*보다 큰 수가 없다, 1*를 인쇄한다: [] - 6번째 인쇄 []: 여기! 
  */

  //주어진 배열의 모든 요소가 다 나갈 때까지 반복할 수 있는데 
  //중간에 인덱스 번호로 찾았다면 끝까지 다 인쇄 안해도 된다. -break사용하기

  //주어진 배열의 모든 요소가 다 나갈 때까지 아래 내용을 반복한다.
    //인쇄 대기 목록의 가장 앞의 문서를 꺼낸다.
    //나머지 목록에서의 최대값을 구한다...&
      // 꺼낸 문서의 값이 &과 같거나 크다: 바로 인쇄하고 다시 처음으로 돌아가 반복한다.
      // 꺼낸 문서의 값이 &보다 작다: 인쇄 대기목록의 가장 마지막에 push한다. 

  //문제점: 같은 숫자들은 인덱스로 반드시 구분할 수 밖에 없으니, 인덱스를 사용해야 한다. 
  //인덱스 저장한 배열을 만든다. 
  //인덱스 저장한 배열도 위 인쇄 과정과 똑같이 조작한다. 
  //이때, 내가 찾고자 하는 인덱스가 존재하는지 존재하지 않는지 확인한다.
  //인덱스가 존재하면 계속 위 과정을 반복한다.
  //인덱스가 처음으로 존재하지 않는 순간(직전에 내가 찾고자 하는 인덱스가 인덱스 배열의 맨 앞에 있음 )
  //(최초 대기목록의 길이 - 인쇄 후 대기 목록의 길이)를 리턴하여야 한다. 

  //최초 대기목록의 길이 저장
  const pLen = priorities.length;

  // 인덱스 저장할 배열만들기
  const indices = [];
  priorities.forEach((el,idx) => {
    indices.push(idx);
  })

  //인쇄 과정 반복하기
  while(priorities.length){
    //일단 대기목록과 인덱스에서 꺼낸다.
    let ptemp = priorities.shift();
    let remainMax = Math.max(...priorities); 
    let itemp = indices.shift();

    if(ptemp >= remainMax){
      //만약에 빼낸 인덱스 itemp가  location과 동일하다면? 전체 과정 종료.
      if(itemp === location) return pLen - priorities.length; ***
      //그렇지 않을땐 바로 인쇄하고, 다음으로 넘어간다. 이때 인덱스도 빼 준다.(위에서 이미했음)
    }else{
      priorities.push(ptemp);
      indices.push(itemp);
    }
  }
}

(4) 다리를 지나는 트럭: 코플릿 프린터 문제와 동일

function solution(bridge_length, weight, truck_weights) {
    let time = 0;
    /*
    다리를 지난 트럭    다리 건너는 트럭    대기 트럭
    []               [|]             [7,4,5,6]
    []               [|7]             [4,5,6]
    []               [7|]             [4,5,6]
    [7]               [|4]             [5,6]
    [7]               [4|5]             [6]
    [7,4]             [5|]              [6]
    [7,4,5]           [|6]              []
    [7,4,5]           [6|]              []
    [7,4,5,6]         [|]
    다리에 트럭이 하나도 없을 때까지 반복해야 한다.
    다리에 대한 배열을 만들고 다 0으로 채운다
    
    */
    const bridge = new Array(bridge_length).fill(0);
    //일단 트럭 한대 빼서 넣기 대기트럭.shift() - *, 
    //뺀 트럭 무게+ 다리 건너는 트럭무게 <= weight : 다리건너는트럭.shift(), 다리건너는트럭.push(*)
    //뺀 트럭 무게+ 다리 건너는 트럭무게 > weight : 다리건너는트럭.shift(), 다리건너는트럭.push(0), 대기트럭.unshift(*)
    //다리에서 모든 트럭이 사라질때까지 반복 === 
    let totalweight = 0;
    let truck = truck_weights.shift();
    bridge.push(truck);
    bridge.shift();
    totalweight += truck;
    time = 1;
    
    while(totalweight){
        truck = truck_weights.shift();
        totalweight -= bridge.shift(); //슬라이딩 윈도 방법
        
        if(weight >= truck + totalweight){
            bridge.push(truck);
            totalweight += truck
        }else{
            bridge.push(0);
            truck_weights.unshift(truck);
        }
        time++;
    }
    return time;
}

DFS/BFS