티스토리 뷰

  • 문제 출처 - 프로그래머스

  • 문제(정확한 문제는 위 링크 참조)

    n개의 노드가 있는 그래프가 있다. 각 노드는 1부터 n까지의 번호가 적혀있다. 최단 경로를 전제했을 때 1번 노드로부터 가장 멀리 떨어진 노드의 개수를 리턴하라. 
    
    

     

  • 입출력 예시 - 자바스크립트 버전

    노드의 개수 n과 간선에 대한 정보가 담긴 2차원 배열 vertex가 매개변수로 주어진다.
    (ex)
    n = 6
    vertex = [[3,6],[4,3],[3,2],[1,3],[1,2],[2,4],[5,2]]
    return 3
    (설명)
    1번 노드로부터 가장 멀리 떨어진 노드는 4,5,6 이므로 3을 리턴
    
    

 

  • 시간 초과 실패한 코드 1

    • BFS, queue를 이용
    function solution(n, edge){
        // 큐의 가장 첫번째 원소를 head로 설정 
        var head = 1;
        
        // 큐를 구현할 배열을 만듦  
        var q = [head];
        
        // 노드 방문 여부를 boolean값으로 저장할 배열 생성
        var b = new Array(n+1);
        b[head] = true; 
        
        // 1번 노드와의 거리를 저장할 배열 생성
        var d = new Array(n+1);
        d[0] = null;
        
        // 시작할 헤드(노드 1)의 거리는 0
        d[head] = 0; 
    	
        // q에 원소가 있는 동안 bfs 탐색하며, 1번 노드와의 거리를 d배열에 저장.  
        while(q.length !== 0) {
            for(var i = 1 ; i <= n ; i++) {
                if(edge.some(v => v.includes(i) && v.includes(head)) && b[i] !== true) {
                    q.push(i);
                    b[i] = true; 
                    d[i] = d[head]+1;
                }
            }
            q.shift();
            head = q[0]; 
        }
        
        // d배열에서 가장 큰 값을 찾은 뒤, 그 값을 갖고 있는 원소의 개수를 세어 리턴
        var max = Math.max(...d);
        return d.filter(i=> i === max).length;
    }
    
    

 

  • 시간 초과로 실패한 코드 2 (1답안 보다 테스트 케이스 더 많이 통과했으나 2개 실패)

    • edge를 매번 전부 탐색하는 부분을 개선. splice를 사용해서 탐색할 때마다 edge 크기를 줄여나감.
    • 그리고 1답안에서는 큐의 원소가 전부 사라질 때까지 탐색했는데 그러면 정작 edge는 텅비었는데 쓸데없이 탐색 하는 횟수가 늘어나서 edge의 원소가 전부 사라질 때까지 while문 돌림
    function solution(n, edge){
        var head = 1;
        var q = [head];
        // 방문 여부
        var b = new Array(n+1);
        b[head] = true; 
        // 현 헤드와의 거리 저장
        var d = new Array(n+1);
        d[0] = null;
        d[head] = 0;   
         
        let j; 
        while(edge.length !== 0) {
            j = 0;
            while(j < edge.length) {
                if(edge[j].includes(head)) {
                    edge[j] = edge[j].filter(k => k !== head);
                    if(!b[edge[j][0]]) {
                        q.push(edge[j][0]); 
                        b[edge[j][0]] = true;
                        d[edge[j][0]] = d[head]+1;
                    }
                    edge.splice(j, 1);
    				j--;
                }
                j++;
            }
    		q.shift();
            head = q[0]; 
        }
    
        var max = Math.max(...d);
    
        return d.filter(i => i === max).length;
    }
    
    

 

  • 테스트 케이스 모조리 다 틀린 코드

    • 왜 몇 개가 통과못하는 것도 아니고 다 틀리지...? 어디가 틀렸는지 잘 모르겠는 코드ㅠㅠ empty 때문인가
    • 탐색하기 쉽도록 구조를 바꾼 다음에 bfs 돌림
    • 그러나 제출 누르자마자 테스트 케이스 다 틀림..
    function solution(n, edge){
        var head = 1;
        var q = [head];
        // 방문 여부
        var b = new Array(n+1);
        b[head] = true; 
        // 현 헤드와의 거리 저장
        var d = new Array(n+1);
        d[0] = null;
        d[head] = 0;   
        
        var arr = [];
        for(var j = 0 ; j < n ; j++) {
            arr.push([]);
        }
    
        for(var i of edge) {
            if(i[0] < i[1]) { 
                arr[i[0]-1][i[1]-1] = 1; 
            } else {
                arr[i[1]-1][i[0]-1] = 1;
            }
        }
    
        while(q.length !== 0) {
            for(var k = head ; k < arr[head-1].length ; k++) {
                if(arr[head-1][k] === 1 && b[k+1] !== true) {
                    q.push(k+1); 
                    b[k+1] = true; 
                    d[k+1] = d[head] + 1; 
                }    
            }
            q.shift(); 
            head = q[0]; 
        }
        
        var max = Math.max(...d);
    
        return d.filter(i => i === max).length;
    }
    

 

  • 다른 분 정답 보고 다시 짠 코드(통과)

    function solution(n, edge) {
        
      	// 2차원 배열 만들기
        const arr = Array(n+1).fill(null).map(()=>Array());
        const queue = [[1,0]];
        const dist = [null];
        
        for(let i of edge) {
            arr[i[0]].push(i[1]);
            arr[i[1]].push(i[0]);
        }
    
        inputQueue(1,1);
    
        while(queue.length > 0) {
            const shifted = queue.shift();
            
          	// 이 조건은 노드 1이 방문한 노드로서 지워지지 않았기 때문
          	if(dist == null)
            	dist[shifted[0]] = shifted[1]; 
    
            inputQueue(shifted[0], dist[shifted[0]] + 1); 
        }
    		
      	// 거리 최대값의 개수 리턴
        const max = Math.max(...dist);
        return dist.filter(i=> i === max).length; 
    
        function inputQueue(i, weight) {
            const len = arr[i].length;
    				
          	// 큐에 푸시
            for(let j=0 ; j < len ; j++) {
                const num = arr[i].shift();
                queue.push([num, weight]); 
                
              	// 방문한 노드 지우기
                for(let k =1 ; k <=n ; k++) {
                    const index = arr[k].indexOf(num);
                    if(index != -1) {
                        arr[k].splice(index,1); 
                    }
                } 
            }
        } 
    }
    

 

'Data Structure & Algorithm' 카테고리의 다른 글

배열과 링크드 리스트  (0) 2019.11.18
[파이썬] 야근지수 문제  (1) 2019.09.23
[Java] LinkedList  (0) 2019.05.31
[Java] Queue  (0) 2019.05.27
[Java] Stack, reverseString  (0) 2019.05.27
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함