[TIL] 211026

Lee SyongΒ·2021λ…„ 10μ›” 26일
0

TIL

λͺ©λ‘ 보기
69/204
post-thumbnail

πŸ“ 였늘 ν•œ 것

  1. ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ 문제 풀이 - μ˜ˆμ‚°

  2. λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜ / 곡간 λ³΅μž‘λ„


πŸ“– ν•™μŠ΅ 자료

  1. μ±… 'λˆ„κ΅¬λ‚˜ 자료 ꡬ쑰와 μ•Œκ³ λ¦¬μ¦˜'

πŸ“š 배운 것

1. ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ 문제 풀이

1) Level 1 문제

(1) μ˜ˆμ‚°

  • Summer/Winter Coding(~2018)

πŸ”Ž λ‚΄κ°€ μž‘μ„±ν•œ 풀이

function solution(d, budget) {
  d.sort((a, b) => b - a);
  let count = 0;
  let pop = d.pop();

  while (budget >= pop) {
    budget = budget - pop;
    pop = d.pop();
    count++;
  }

  return count;
}

13μž₯. κ·Έλž˜ν”„λ‘œ 뭐든지 μ—°κ²°ν•˜κΈ°

μ–΄μ œ 곡뢀에 μ΄μ–΄μ„œ

5) λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜(Dijkstra Algorithm)

  • κ°€μ€‘μΉ˜ κ·Έλž˜ν”„λ₯Ό μ΄μš©ν•΄ μ΅œλ‹¨ 경둜 문제λ₯Ό ν‘ΈλŠ” μ•Œκ³ λ¦¬μ¦˜

  • κ°€μ€‘μΉ˜λ₯Ό 각 λ„μ‹œμ—μ„œ λ‹€λ₯Έ λ„μ‹œλ‘œ 갈 λ•Œ μ–Όλ§ˆλ‚˜ 빨리 갈 수 μžˆλŠλƒλ‘œ ν‘œν˜„ν•¨μœΌλ‘œμ¨, 맀핑과 GPS κΈ°μˆ μ—μ„œ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€. 이λ₯Ό 톡해 ν•œ μž₯μ†Œμ—μ„œ λ‹€λ₯Έ μž₯μ†Œλ‘œ μš΄μ „ν•  λ•Œ μ–΄λ–€ 경둜둜 κ°€μ•Ό 할지 κ²°μ •ν•  수 μžˆλ‹€.

  • μ•„λž˜μ—μ„œλŠ” κ°€μ€‘μΉ˜λ₯Ό κ°€κ²©μœΌλ‘œ ν‘œν˜„ν•œ 예제λ₯Ό μ‚΄νŽ΄λ³Ό 것이닀.

(1) μ„€λͺ…

[ 예제 ]

μ• ν‹€λž€νƒ€λ‘œλΆ€ν„° λ‹€λ₯Έ λ„μ‹œλ“€κΉŒμ§€μ˜ κ°€μž₯ μ €λ ΄ν•œ 경둜λ₯Ό 기둝해라

[ μ½”λ“œ μ„€λͺ… ]

  1. μ‹œμž‘ 정점을 ν˜„μž¬ μ •μ μœΌλ‘œ ν•œλ‹€.

  2. ν˜„μž¬ 정점에 μΈμ ‘ν•œ λͺ¨λ“  정점을 ν™•μΈν•΄μ„œ, μ‹œμž‘ μ •μ μœΌλ‘œλΆ€ν„°, μ•Œλ €μ§„ λͺ¨λ“  μœ„μΉ˜κΉŒμ§€μ˜ κ°€μ€‘μΉ˜λ₯Ό κ³„μ‚°ν•˜κ³  κΈ°λ‘ν•œλ‹€.

  3. λ‹€μŒ ν˜„μž¬ 정점을 κ²°μ •ν•˜λ €λ©΄, μ‹œμž‘ μ •μ μœΌλ‘œλΆ€ν„° 도달할 수 μžˆλŠ”, λ°©λ¬Έν•˜μ§€ μ•Šμ€, κ°€μž₯ μ €λ ΄ν•œ, μ•Œλ €μ§„, 정점을 μ°ΎλŠ”λ‹€.

  4. κ·Έλž˜ν”„ λ‚΄ λͺ¨λ“  정점을 λ°©λ¬Έν•  λ•ŒκΉŒμ§€ 1 ~ 3 단계λ₯Ό λ°˜λ³΅ν•œλ‹€.

(2) μ½”λ“œ κ΅¬ν˜„

pp.292 ~ 294
Ruby둜 κ΅¬ν˜„λœ μ½”λ“œ β†’ JavaScript둜 λ³€ν™˜

πŸ™‹β€β™€οΈ Q1. λ―Έμ™„μ„± μ½”λ“œλ‹€. 였λ₯˜κ°€ λ°œμƒν–ˆλŠ”λ° 더 이상 μ–΄λ–»κ²Œ μˆ˜μ •ν•΄μ•Ό 할지 λͺ¨λ₯΄κ² λ‹€. λ°œμƒν•œ 였λ₯˜λŠ” μ•„λž˜μ™€ κ°™λ‹€. (μ½”λ“œ μ°Έκ³ )

Uncaught TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at dijkstra (πŸ™‹β€β™€οΈ Q1(1))
    at πŸ™‹β€β™€οΈ Q1(2)

β†’ πŸ’‘ 원인은 μ•Œκ² λŠ”λ° μ–΄λ–»κ²Œ 고쳐야 ν•˜λŠ”μ§€λ₯Ό λͺ¨λ₯΄κ² λ‹€.

πŸ™‹β€β™€οΈ Q2. μœ„ 였λ₯˜κ°€ λ°œμƒν•œ 원인 같은데 해결을 λͺ»ν•˜κ² λ‹€. (μ½”λ“œ μ°Έκ³ )
β†’ πŸ’‘ A2 μ°Έκ³ 

class City {
  constructor(name) {
    this.name = name;
    this.routes = {};
    this.visited = false;
  }

  add_route(city, price_info) {
    this.routes[city] = price_info;
  }
}

// 가쀑 κ·Έλž˜ν”„ λ§Œλ“€κΈ°
const atlanta = new City('atlanta');
const boston = new City('boston');
const chicago = new City('chicago');
const denver = new City('denver');
const elpaso = new City('elpaso');


atlanta.add_route(boston, 100);
atlanta.add_route(denver, 160);
boston.add_route(chicago, 120);
boston.add_route(denver, 180);
chicago.add_route(elpaso, 80);
denver.add_route(chicago, 40);
denver.add_route(elpaso, 140);
elpaso.add_route(boston, 100);
/* πŸ™‹β€β™€οΈ Q2. μ΄λ ‡κ²Œ μ“΄ ν›„ μ½˜μ†” 창에 atlantaλ₯Ό 좜λ ₯ν•˜λ‹ˆκΉŒ {'[object Object]': 160}이 λ‚˜μ˜¨λ‹€.
심지어 atlanta.routes[chicago]λ₯Ό 좜λ ₯해도 160이 λ‚˜μ˜¨λ‹€.
ν…ŒμŠ€νŠΈ ν•΄λ³΄λ‹ˆκΉŒ atlanta.routes[였브젝트]λ₯Ό 좜λ ₯ν•˜λ©΄ μ–΄λ–€ 였브젝트건 간에 160이 λ‚˜μ˜¨λ‹€.
이게 μ™œ μ΄λ ‡κ²Œ λ˜λŠ” 건지 λͺ¨λ₯΄κ² λ‹€. */

/* κ·Έλž˜μ„œ λ°‘μ˜ λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜ μ½”λ“œλŠ” μ•„λž˜ μ£Όμ„μ²˜λŸΌ boston.name, denver.name이라고 μ“΄ μƒνƒœλ‘œ κ΅¬ν˜„μ„ ν–ˆλ‹€.
근데 μ΄λ²ˆμ—” μ•„λ§ˆλ„ 이것 λ•Œλ¬Έμ— λ°‘μ—μ„œ 였λ₯˜κ°€ λœ¨λŠ” κ±° κ°™λ‹€...*/
// atlanta.add_route(boston.name, 100);
// atlanta.add_route(denver.name, 160);

/* πŸ’‘ A2. add_route ν•¨μˆ˜λŠ” 첫 번째 인자둜 cityλ₯Ό λ°›λŠ”λ° μ „ν•΄μ£ΌλŠ” 값이 λ¬Έμžμ—΄μ΄ μ•„λ‹Œ objectλΌμ„œ μ—λŸ¬κ°€ 생긴 것
λ‹€μ΅μŠ€νŠΈλΌ μ•Œκ³ λ¦¬μ¦˜μ΄λž‘ μ „ν˜€ μƒκ΄€μ—†λŠ” μ—λŸ¬μ˜€...γ…Žγ…Ž */


// πŸ”₯ λ‹€μ΅μŠ€νŠΈλΌμ˜ μ•Œκ³ λ¦¬μ¦˜ (μ–΄λŠ λ„μ‹œμ—μ„œ λ‹€λ₯Έ λ„μ‹œλ“€λ‘œ κ°€λŠ” 각각의 κ°€μž₯ μ €λ ΄ν•œ 경둜 κ΅¬ν•˜κΈ°)
function dijkstra(starting_city, other_cities) {
  // λ„μ‹œ : [μ‹œμž‘ λ„μ‹œλ‘œλΆ€ν„° 이 λ„μ‹œκΉŒμ§€μ˜ κ°€μž₯ μ €λ ΄ν•œ 가격, ν•΄λ‹Ή κ²½λ‘œμ—μ„œ 이 λ„μ‹œ λ°”λ‘œ 전에 λ“€λ₯΄λŠ” λ„μ‹œ]
  const routes_from_city = {};

  // μ‹œμž‘ λ„μ‹œμ—μ„œ μ‹œμž‘ λ„μ‹œλ‘œ κ°€λŠ” λΉ„μš©μ€ 0
  routes_from_city[starting_city] = [0, starting_city];

  // λ‹€λ₯Έ λ„μ‹œλ“€ 데이터 μ΄ˆκΈ°ν™” (μ‹œμž‘ λ„μ‹œ 외에 λ‹€λ₯Έ λ„μ‹œλ“€λ‘œ κ°€λŠ” λΉ„μš©κ³Ό κ²½λ‘œλŠ” 아직 μ•Œλ €μ§€μ§€ μ•Šμ•˜μœΌλ―€λ‘œ 일단 λ¬΄ν•œλŒ€ κ°’ ν• λ‹Ή)
  other_cities.forEach(city => routes_from_city[city] = [Infinity, null]);
  console.log(routes_from_city);

  // λ°©λ¬Έν–ˆλ˜ λ„μ‹œ 기둝
  const visited_cities = [];

  // μ‹œμž‘ λ„μ‹œλ₯Ό ν˜„μž¬ λ„μ‹œ[정점]둜 지정
  let curr_city = starting_city;

  // 각 λ„μ‹œλ₯Ό λ°©λ¬Έν•˜λŠ” 루프 μ‹œμž‘
  while(curr_city) {
    visited_cities.push(curr_city);

    // ν˜„μž¬ λ„μ‹œλ‘œλΆ€ν„° 각 경둜λ₯Ό 확인
    Object.keys(curr_city.routes).forEach(city => { // πŸ™‹β€β™€οΈ Q1(1)
      if (routes_from_city[city][0] > curr_city.routes[city] + routes_from_city[curr_city][0]) {
        routes_from_city[city] = [curr_city.routes[city] + routes_from_city[curr_city][0], curr_city]
      }
    });

    // λ‹€μŒμœΌλ‘œ λ°©λ¬Έν•  λ„μ‹œ κ²°μ •
    curr_city = null;
    let cheapest_route_from_curr_city = Infinity;
    Object.keys(routes_from_city).forEach(city => {
      if (routes_from_city[city][0] < cheapest_route_from_curr_city && !visited_cities.includes(city)) {
        cheapest_route_from_curr_city = routes_from_city[city][0];
        curr_city = city;
      }
    });
  }

  return routes_from_city;
}

const route = dijkstra(atlanta, ['boston', 'chicago', 'denver', 'elpaso']);
// πŸ™‹β€β™€οΈ Q1(2)

Object.keys(route).forEach(city => console.log(`city: ${city}, price_info: ${route[city][0]}`));

14μž₯. 곡간 μ œμ•½ 닀루기

πŸ“Œ μ‹œκ°„ λ³΅μž‘λ„ : 자료 κ΅¬μ‘°λ‚˜ μ•Œκ³ λ¦¬μ¦˜μ΄ μ™„λ£ŒκΉŒμ§€ μ–Όλ§ˆλ‚˜ λ§Žμ€ 단계가 κ±Έλ¦¬λŠλƒ

πŸ“Œ 곡간 λ³΅μž‘λ„ : 자료 κ΅¬μ‘°λ‚˜ μ•Œκ³ λ¦¬μ¦˜μ΄ μ™„λ£ŒκΉŒμ§€ μ–Όλ§ˆλ‚˜ λ§Žμ€ λ©”λͺ¨λ¦¬λ₯Ό μ†ŒλΉ„ν•˜λŠλƒ

1) λΉ… 였 ν‘œκΈ°λ²•

πŸ’‘ μ•Œκ³ λ¦¬μ¦˜μ˜ νš¨μœ¨μ„±

  • μ•Œκ³ λ¦¬μ¦˜μ˜ 속도

    데이터 μ›μ†Œκ°€ N개일 λ•Œ, μ•Œκ³ λ¦¬μ¦˜μ€ N에 λΉ„λ‘€ν•˜λŠ” μ—°μ‚° 단계가 κ±Έλ¦°λ‹€.

  • μ•Œκ³ λ¦¬μ¦˜μ— μ΅œλŒ€ μ–Όλ§ˆλ‚˜ λ§Žμ€ 곡간이 ν•„μš”ν•œκ°€

    데이터 μ›μ†Œκ°€ N개일 λ•Œ, μ•Œκ³ λ¦¬μ¦˜μ€ λ©”λͺ¨λ¦¬ λ‚΄ μΆ”κ°€λ‘œ λ“€μ–΄ μžˆλŠ” 데이터 μ›μ†Œ μˆ˜μ— λΉ„λ‘€ν•΄μ„œ 곡간을 μ†Œλͺ¨ν•œλ‹€.

πŸ’‘ λ“€μ–΄κ°€κΈ° 전에 μ•žμ„œ, 'μ—¬κΈ°μ„œλŠ”' 곡간 λ³΅μž‘λ„λ₯Ό 계산할 λ•Œ μΆ”κ°€λ‘œ μ†ŒλΉ„λ˜λŠ” λ©”λͺ¨λ¦¬(보쑰 곡간)λ§Œμ„ κ³ λ €ν•œλ‹€. 즉, μ›λž˜ λ°μ΄ν„°λŠ” 계산 μ‹œ ν¬ν•¨ν•˜μ§€ μ•ŠλŠ”λ‹€.

(1) O(N)

function makeUpperCase(arr) {
  const newArr = [];
  for (let i = 0; i < arr.length; i++) {
    newArr[i] = arr[i].toUpperCase();
  }
  return newArr;
}

μœ„ ν•¨μˆ˜λŠ” μ›μ†Œ N개λ₯Ό λ°›μ•„ μ›μ†Œ N개인 μƒˆλ‘œμš΄ 배열을 μƒμ„±ν•œλ‹€.
예λ₯Ό λ“€μ–΄, μ›λž˜ λ°°μ—΄μ˜ μ›μ†Œκ°€ 5개, 10개이면 μ›μ†Œμ˜ κ°œμˆ˜κ°€ 5개, 10개인 μƒˆλ‘œμš΄ 배열을 μƒμ„±ν•œλ‹€.

λ”°λΌμ„œ, 곡간 νš¨μœ¨μ„±μ€ O(N)이닀.
λ°μ΄ν„°μ˜ 크기가 N개면, μΆ”κ°€λ‘œ μ†ŒλΉ„ν•˜λŠ” 곡간은 N이 λœλ‹€.

(2) O(1)

function makeUpperCase(arr) {
  for (let i = 0; i < arr.length; i++) {
    arr[i] = arr[i].toUpperCase();
  }
  return arr;
}

μœ„ ν•¨μˆ˜λŠ” μƒˆ λ³€μˆ˜λ‚˜ μƒˆ 배열을 μƒμ„±ν•˜μ§€ μ•ŠλŠ”λ‹€.
예λ₯Ό λ“€μ–΄, μ›λž˜ λ°°μ—΄μ˜ μ›μ†Œκ°€ 5κ°œλ“  10κ°œλ“  μ›λž˜ λ°°μ—΄ 외에 μ–΄λ–€ λ©”λͺ¨λ¦¬λ„ 쓰지 μ•ŠλŠ”λ‹€.

λ”°λΌμ„œ, 곡간 νš¨μœ¨μ„±μ€ O(1)이닀.
λ°μ΄ν„°μ˜ 크기와 상관없이, μΆ”κ°€λ‘œ μ†ŒλΉ„ν•˜λŠ” 곡간은 0으둜 항상 κ°™λ‹€.

μ‹œκ°„ λ³΅μž‘λ„μ—μ„œ O(1)은, λ°μ΄ν„°μ˜ 크기와 상관없이, μ•Œκ³ λ¦¬μ¦˜ 속도가 μƒμˆ˜λΌλŠ” λœ»μ΄λ‹€. 곡간 λ³΅μž‘λ„μ—μ„œ O(1)은, λ°μ΄ν„°μ˜ 크기와 상관없이, μ•Œκ³ λ¦¬μ¦˜μ΄ μ†Œλͺ¨ν•˜λŠ” λ©”λͺ¨λ¦¬κ°€ μƒμˆ˜λΌλŠ” λœ»μ΄λ‹€.

2) μ‹œκ°„κ³Ό 곡간 νŠΈλ ˆμ΄λ“œ μ˜€ν”„

[ 예제 ]

배열에 쀑볡 값이 μžˆλŠ”μ§€ ν™•μΈν•˜λŠ” μ½”λ“œ

// 버전 1
function hasDuplicateValue(arr) {
  const newArr = [];
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] === arr[j]) {
        return true;
      }
    }
  }
  return false;
}
// 버전 2
function hasDuplicateValue(arr) {
  const checkedValue = [];
  for (let i = 0; i < arr.length; i++) {
    if (checkedValue[arr[i]] === undefined) {
      checkedValue[arr[i]] = 1;
    } else {
      return true;
    }
  }
  return false;
}
  • νš¨μœ¨μ„± 비ꡐ

    μ‹œκ°„ λ³΅μž‘λ„κ³΅κ°„ λ³΅μž‘λ„
    버전 1O(N^2)O(1)
    버전 2O(N)O(N)
  • 상황에 따라 μ•Œλ§žμ€ 버전을 골라 써야 ν•œλ‹€


✨ 내일 ν•  것

  1. ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ 문제 풀이
profile
λŠ₯λ™μ μœΌλ‘œ μ‚΄μž, ν–‰λ³΅ν•˜κ²ŒπŸ˜

0개의 λŒ“κΈ€