[프로그래머스 lev2/JS] 배달

woolee의 기록보관소·2022년 12월 6일
0

알고리즘 문제풀이

목록 보기
117/178

문제 출처

프로그래머스 lev2 - 배달

나의 풀이

1차시도(21.9/100)

function solution(N, road, K) {
  let tw = new Map();
  for(let i=1; i<=N; i++) tw.set(i, [])

  road.map(v => {
    const [a, b, weight] = v;

    tw.get(a).push([b, weight]);
    tw.get(b).push([a, weight]);
  });

  let dist = [];
  dist[1] = 0;

  for(let cur of tw.keys()) {
    // console.log(cur);
    for(let tmp of tw.get(cur)) {
      const [des, weight] = tmp;
      // console.log(tmp);
      if(cur === 1) dist[des] = weight;

      if(dist[cur] && cur < des) {
        if(dist[des]) {
          dist[des] = Math.min(dist[des], dist[cur] + weight);
        } else dist[des] = dist[cur] + weight;
      }
    }
  }

  // console.log(dist);
  let answer = 0;
  for(let i=1; i<dist.length; i++) {
    if (dist[i] <= K) answer++;
  }

  return answer;
}

2차시도(50/100)

function solution(N, road, K) {
  let tw = new Map();
  for(let i=1; i<=N; i++) tw.set(i, [])

  road.map(v => {
    const [a, b, weight] = v;

    tw.get(a).push([b, weight]);
    tw.get(b).push([a, weight]);
  });

  let dist = Array.from({length:N+1}, () => Number.MAX_SAFE_INTEGER);
  dist[1] = 0;

  // console.log(tw);

  for(const cur of tw.keys()) {
    // console.log(cur);
    for(const tmp of tw.get(cur)) {
      const [des, weight] = tmp;

      if(cur === 1 && des !== 1) dist[des] = Math.min(dist[des], weight);
      if(des === 1 && cur !== 1) dist[cur] = Math.min(dist[cur], weight);

      else if(cur !== 1 && des !== 1){
        dist[des] = Math.min(dist[des], dist[cur] + weight);
        dist[cur] = Math.min(dist[cur], dist[des] + weight);
      }
      // console.log(tmp);
      // console.log(dist);
    }
  }

  // console.log(dist)

  let answer = 0;
  for(let i=1; i<dist.length; i++) {
    if (dist[i] <= K) answer++;
  }

  return answer;
}

3차시도(56.3/100)

단순히 for 전진으로 진행하면 앞쪽에서 제대로 계산되지 않은 부분이 생기므로 while문으로 꼼꼼히 해야 할 것 같은데..

function solution(N, road, K) {
  let tw = new Map();
  for(let i=1; i<=N; i++) tw.set(i, [])

  road.map(v => {
    const [a, b, weight] = v;

    tw.get(a).push([b, weight]);
    tw.get(b).push([a, weight]);
  });

  let dist = Array.from({length:N+1}, () => Number.MAX_SAFE_INTEGER);
  dist[0] = 0;
  dist[1] = 0;

  // console.log(tw);
  let sum = dist.reduce((a,b) => a+b);
  while(sum > Number.MAX_SAFE_INTEGER) {
    for(const cur of tw.keys()) {
      // console.log(cur);
      for(const tmp of tw.get(cur)) {
        const [des, weight] = tmp;
  
        if(cur === 1 && des !== 1) dist[des] = Math.min(dist[des], weight);
        if(des === 1 && cur !== 1) dist[cur] = Math.min(dist[cur], weight);
  
        else if(cur !== 1 && des !== 1){
          dist[des] = Math.min(dist[des], dist[cur] + weight);
          dist[cur] = Math.min(dist[cur], dist[des] + weight);
        }
        // console.log(tmp);
        // console.log(dist);
      }
    }
    sum = dist.reduce((a,b) => a+b);
  }
  // console.log(dist)
  let answer = 0;
  for(let i=1; i<dist.length; i++) {
    if (dist[i] <= K) answer++;
  }

  return answer;
}

4차시도(통과)

경로 계산에서 누락되는 부분이 계속 발생하는 것 같아서 완전탐색을 해야 한다고 판단했다. 그중 BFS를 택했다. (정점들이 다층적으로 깊게 연결되어 있기 보다는 하나의 정점에 여러 개가 연결되어 있는 느낌이라서.. 깊게 들어가는 것보다는 넓게 들어가는 형태가 적합하다고 생각했다)

최단거리를 찾으려면 현재 계층에서 최대한 훑어보는 bfs가 적합해 보이고,
최대값을 찾으려면 계층을 깊게 들어가서 판단해보는 dfs가 더 어울리는 것 같기도 하고...이건 잘 모르겠다..

dist의 초기값은 Number.MAX_SAFE_INTEGER이므로
if(dist[des] > dist[b] + weight)는 무조건 1회 이상은 발생한다. 이외 상황에서는 굳이 가지를 뻗어나갈 필요가 없고 최단경로에 대해서만 가지를 뻗어나가면 된다.

Dijkstra
Floyd-Warshall

function solution(N, road, K) {
  let tw = new Map();
  for(let i=1; i<=N; i++) tw.set(i, [])

  road.map(v => {
    const [a, b, weight] = v;

    tw.get(a).push([b, weight]);
    tw.get(b).push([a, weight]);
  });

  let dist = Array.from({length:N+1}, () => Number.MAX_SAFE_INTEGER);
  
  const queue = [[1, 0]];
  dist[1] = 0;
  console.log(tw);

  while(queue.length) {
    console.log(queue);
    let [b, _] = queue.pop();

    tw.get(b).map(el => {
      let [des, weight] = el;

      if(dist[des] > dist[b] + weight) {
        dist[des] = dist[b] + weight;
        queue.push(el);
      }
    })
  }
  // console.log(dist);
  return dist.filter(el => el <= K).length;
}

console.log(solution(6, [
  [1, 2, 1], 
  [1, 3, 2], 
  [2, 3, 2], 
  [3, 4, 3], 
  [3, 5, 2], 
  [3, 5, 3], 
  [5, 6, 1]], 4)) // 4
profile
https://medium.com/@wooleejaan

0개의 댓글