백준 16964 < DFS 스페셜 저지 > JavaScript

2023. 1. 11.·☕️ 커리어 & 인터뷰 준비/코딩 테스트

📍문제 링크

https://www.acmicpc.net/problem/16964

 

16964번: DFS 스페셜 저지

첫째 줄에 정점의 수 N(2 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N-1개의 줄에는 트리의 간선 정보가 주어진다. 마지막 줄에는 DFS 방문 순서가 주어진다. DFS 방문 순서는 항상 N개의 정수로 이루

www.acmicpc.net

 

📍알고리즘 분류

- 자료구조

- 그래프 이론

- 그래프 탐색

- 깊이 우선 탐색

 

📍문제 풀이

인접 리스트를 만들 수 있는 정보와, 경로가 주어질 때, 주어진 경로가 DFS를 만족하는 경로인지 확인하라

 

📍의사 코드

경로의 현재 값을 A, 다음 값을 B라고 할 때,

1️⃣주어진 경로를 순회하며, A 와 B를 비교하는 반복문을 만든다

2️⃣분기

- A의 이웃 중에 B가 있으면 continue

- 아닌 경우, A의 이웃 중에 방문 이력이 없는 노드가 존재하면 DFS 경로가 아님

/*
아래 그래프 형태일 때,

1 - 2
|     \
3      4

경로가 1 2 3 4 라면,
      ---
      OK
        ---
        NG -> 2의 이웃중 3이 방문 이력이 없는 정점이므로
 */

 

📍코드 (JavaScript)

const [in1, ...in2] = require("fs")
  .readFileSync("/dev/stdin")
  .toString()
  .trim()
  .split("\n");

const N = +in1;
const path = in2.pop().split(" ").map(Number);
const data = in2.map((el) => el.split(" ").map(Number));

class Graph {
  constructor() {
    this.adjacencyList = {};
  }
  addVertex(num) {
    for (let i = 1; i <= num; i++) {
      this.adjacencyList[i] = [];
    }
  }
  addEdge(data) {
    data.map((edge) => {
      this.adjacencyList[edge[0]].push(edge[1]);
      this.adjacencyList[edge[1]].push(edge[0]);
    });
  }
  dfs(path) {
    let answer = 1;
    if (path[0] !== 1) answer = 0;
    const isVisited = {};
    for (let i = 0; i < path.length - 1; i++) {
      isVisited[path[i]] = true;
      if (this.adjacencyList[path[i]].includes(path[i + 1])) continue;
      this.adjacencyList[path[i]].forEach((neighbor) => {
        if (!isVisited[neighbor]) answer = 0;
      });
    }
    return answer;
  }
}

const g = new Graph();
g.addVertex(N);
g.addEdge(data);

console.log(g.dfs(path));

 

📍리팩토링

const [in1, ...in2] = require("fs")
  .readFileSync("/dev/stdin")
  .toString()
  .trim()
  .split("\n");

const N = +in1;
const path = in2.pop().split(" ").map(Number);
const data = in2.map((el) => el.split(" ").map(Number));

class Graph {
  constructor() {
    this.adjacencyList = {};
  }
  addVertex(num) {
    for (let i = 1; i <= num; i++) {
      this.adjacencyList[i] = [];
    }
  }
  addEdge(data) {
    data.map((edge) => {
      this.adjacencyList[edge[0]].push(edge[1]);
      this.adjacencyList[edge[1]].push(edge[0]);
    });
  }
  dfs(path) {
    if (path[0] !== 1) return 0;
    const isVisited = {};
    for (let i = 0; i < path.length - 1; i++) {
      isVisited[path[i]] = true;
      if (this.adjacencyList[path[i]].includes(path[i + 1])) continue;
      for (let neighbor of this.adjacencyList[path[i]]) {
        if (!isVisited[neighbor]) return 0; // 바로 종료
      }
    }
    return 1;
  }
}

const g = new Graph();
g.addVertex(N);
g.addEdge(data);

console.log(g.dfs(path));

 

0을 리턴하고 바로 종료하게 작성하여 시간복잡도를 줄이려 했으나, 오히려 시간 복잡도가 16ms 증가했다 (무의미)

게다가 메모리도 10MB 정도 더 씀..

'☕️ 커리어 & 인터뷰 준비/코딩 테스트' 카테고리의 다른 글
  • 백준 2563 < 색종이 > Python
  • 백준 9655 < 돌 게임 > JavaScript
  • 백준 1057 < 토너먼트 > Python
  • 백준 1240 < 노드사이의 거리 > JavaScript
지식물원
지식물원
지식이 자라는 식물원!
  • 지식물원
    지식물원
    지식물원
  • 전체
    오늘
    어제
    • 분류 전체보기 (516)
      • 🎨 프론트엔드 공부 (253)
        • JS & TS (92)
        • HTML & CSS (22)
        • React & Next (49)
        • Vue & Nuxt (22)
        • 기타 (68)
      • 🤓 기술 학습 & 공부 기록 (116)
        • Node.js (0)
        • Python (37)
        • 백엔드 (0)
        • 딥러닝 (1)
        • 컴퓨터 일반 (72)
        • 개발 인프라 (6)
      • 👨‍💻 프로젝트 경험 (6)
        • Work (0)
        • Toy (6)
      • ⚙️ 개발 팁 & 노하우 (21)
        • 프론트엔드 (6)
        • 기타 (15)
      • ☕️ 커리어 & 인터뷰 준비 (88)
        • 코딩 테스트 (88)
      • 📰 기술 트렌드 & 생각 정리 (4)
      • 📚 기타 (25)
        • 마케팅 (15)
        • 비개발서적 (10)
  • 블로그 메뉴

    • 태그
  • 링크

  • 공지사항

    • 모바일 접속 시 코드 하이라이팅 깨질 때
  • 인기 글

  • hELLO· Designed By정상우.v4.10.3
지식물원
백준 16964 < DFS 스페셜 저지 > JavaScript
상단으로

티스토리툴바