Search
Duplicate
📒

[LeetCode Top 150] 07-1. Clone Graph

상태
완료
수업
Algorithm Solving
주제
LeetCode Top Interview 150
4 more properties
참고

문제해설

문제 로직고민

NOTE
// 1. 초기 node 복제, val의 범위는 1~100 Node clone = new Node(node.val); Node[] nodesClone = new Node[101]; // 2. DFS 탐색 (원본과 복제 node를 둘다 dfs로 돌림) Stack stack = new Stack(); Stack stackClonde = new Stack(); Set visited = new HashSet(); stack.add(node); visited.add(node.val, ); while(!stack.isEmpty()) Node cur = stack.pop(); Node curClone = stackClone.pop(); for(Node n : current.neighbors) if !visited.contains(n.val) visited.add(n.val); stack.push(n); // node가 이미 복제되어있는가를 확 if(cloneNodes[n.val] == null) cloneNodes[n.val] = new Node(n.val); Node clone = cloneNodes[n.val] // 무방향 그래프이므로 양쪽 연결 clone.neighbors.add(curClone); curClone.neighbors.add(clone); stackClone.push(clone); // 4. 반환 return clone;
Java
복사
모든 그래프의 node를 복제하기 위해선 먼저 탐색이 먼저 진행되어야 한다.
DFS방식을 채택하고, 초기 node를 이용해 복제 node를 생성한다.
이후 탐색하면서 node의 정보들을 이용해 새로운 node를 만들고 연결해준다.

작성코드

NOTE
class Solution { public Node cloneGraph(Node node) { if(node == null) return node; Node[] cloneNodes = new Node[101]; Node cloneNode = new Node(node.val); cloneNodes[node.val] = cloneNode; Stack<Node> stack = new Stack(); Stack<Node> stackClone = new Stack(); Set<Integer> visited= new HashSet(); stack.push(node); stackClone.push(cloneNode); visited.add(node.val); while(!stack.isEmpty()){ Node cur = stack.pop(); Node curClone = stackClone.pop(); for(Node n : cur.neighbors){ if(cloneNodes[n.val] == null) cloneNodes[n.val] = new Node(n.val); Node clone = cloneNodes[n.val]; if(!visited.contains(n.val)){ visited.add(n.val); stack.push(n); clone.neighbors.add(curClone); curClone.neighbors.add(clone); stackClone.push(clone); } } } return cloneNode; } }
Java
복사
실패
실패 했는데 이유가 무엇일까?
현재 방식의 탐색으로는 순환이 있다면 모든 간선을 사용하지 않는다!
1 → 2 → 3 → 4 까지 이루어지고, 4-1 간선이 처리가 안됨
무방향을 처리하기 위해 방문하지 않은 노드지점이 나오면 양쪽으로 추가해주었다.
이 방식말고 각 노드의 모든 간선을 방향이 있다 생각하고 추가하는 방식으로 수정한다.
class Solution { public Node cloneGraph(Node node) { if(node == null) return node; Node[] cloneNodes = new Node[101]; Node cloneNode = new Node(node.val); cloneNodes[node.val] = cloneNode; Stack<Node> stack = new Stack(); Stack<Node> stackClone = new Stack(); Set<Integer> visited= new HashSet(); stack.push(node); stackClone.push(cloneNode); visited.add(node.val); while(!stack.isEmpty()){ Node cur = stack.pop(); Node curClone = stackClone.pop(); for(Node n : cur.neighbors){ // 수정한 부분! if(cloneNodes[n.val] == null) cloneNodes[n.val] = new Node(n.val); Node clone = cloneNodes[n.val]; clone.neighbors.add(curClone); if(!visited.contains(n.val)){ visited.add(n.val); stack.push(n); stackClone.push(clone); } } } return cloneNode; } }
Java
복사

다른사람 풀이

NOTE
class Solution { public Node cloneGraph(Node node) { if (node == null) { return null; } return cloneGraph(node, new HashMap<>()); } public Node cloneGraph(Node node, Map<Integer, Node> visited) { if (visited.containsKey(node.val)) { return visited.get(node.val); } ArrayList<Node> newNeighbors = new ArrayList<>(); Node newNode = new Node(node.val, newNeighbors); visited.put(node.val, newNode); for (Node neighbor : node.neighbors) { newNeighbors.add(cloneGraph(neighbor, visited)); } return newNode; } }
Java
복사
실행시간이 빠른 코드
DFS방식을 동일하게 사용했는데 보다 효율적인 코드로 작성했다.
class Solution { public Node cloneGraph(Node node) { // BFS approach if(node==null) { return null; } Queue<Node> q = new ArrayDeque<>(); Map<Node, Node> map = new HashMap<>(); q.offer(node); map.put(node, new Node(node.val)); while(!q.isEmpty()) { Node u = q.poll(); for(Node v: u.neighbors) { if(!map.containsKey(v)) { q.offer(v); map.put(v, new Node(v.val)); } map.get(u).neighbors.add(map.get(v)); } } return map.get(node); } }
Java
복사
전체탐색이므로 BFS역시 마찬가지로 사용이 가능하다.