力扣133. 克隆图

原题链接

题目过长,不复制了
简单来说就是给个图,然后让完全复制一份,不能引用原来的结点,就是不能直接return原来的node,也不能新创建一个node把临边赋值一份就算完。


分析:
这直接dfs一遍或者bfs一遍就行了,第一种思路是先创建结点,然后用一个哈希表去把原结点和复制结点一一对应,在跑一边,把边连上即可。

另一种思路是同时复制边和点。

/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> neighbors;
    public Node() {
        val = 0;
        neighbors = new ArrayList<Node>();
    }
    public Node(int _val) {
        val = _val;
        neighbors = new ArrayList<Node>();
    }
    public Node(int _val, ArrayList<Node> _neighbors) {
        val = _val;
        neighbors = _neighbors;
    }
}
*/

class Solution {
    
    
    Map<Node, Node> map = new HashMap<>();
    public Node cloneGraph(Node node) {
    
    
        if (node == null) return null; // lc特色,非得卡我一次
        // dfs先把点都复制下来
        dfs(node);
        for (Node p : map.keySet()) {
    
     // 枚举哈希表的每一个点,将他的边复制给新的点
            Node copy = map.get(p);
            // p是原点  copy是新的点
            for (Node neighbor : p.neighbors) {
    
     // 枚举原点的邻点
            	// map.get(neighbor)是原点的邻点的复制点,即应该被链接的那个点
            	// 复制点去链接这个邻接点
                copy.neighbors.add(map.get(neighbor));
            }
        }
        return map.get(node);
    }
    void dfs(Node node) {
    
    
    	// 创建新的结点并且做映射
        map.put(node, new Node(node.val));
        for (Node p : node.neighbors) {
    
    
        	// 枚举旁边的点,如果没创建过,就遍历回去,如果不判断就会死循环
            if (!map.containsKey(p))
                dfs(p);
        }
    }

}
/*
// Definition for a Node.
class Node {
    public int val;
    public List<Node> neighbors;
    public Node() {
        val = 0;
        neighbors = new ArrayList<Node>();
    }
    public Node(int _val) {
        val = _val;
        neighbors = new ArrayList<Node>();
    }
    public Node(int _val, ArrayList<Node> _neighbors) {
        val = _val;
        neighbors = _neighbors;
    }
}
*/

class Solution {
    
    
    Map<Node, Node> map = new HashMap<>();
    public Node cloneGraph(Node node) {
    
    
        if (node == null) return null;
        // 先把跟放进来,这步是个特殊处理,dfs里面没办法写了
        map.put(node, new Node(node.val));
        dfs(node);
        return map.get(node);
    }
    void dfs(Node node) {
    
    
        
        for (Node p : node.neighbors) {
    
    
        	// 如果当前结点的邻接点还没有复制过的话
            if (!map.containsKey(p)) {
    
    
            	// 1. 复制进去,并且打个标记,这里的map其实就是一个标记作用的,完全可以想办法替代掉。
            	// 但是上面的代码就不行了,因为没有map就无法找到复制点了
                map.put(p, new Node(p.val));
                // 同时建立边的关系
                map.get(node).neighbors.add(map.get(p));
                // 搜索
                dfs(p);
            } else {
    
    
            	// 如果已经被复制过了,那加一条反向边即可
                map.get(node).neighbors.add(map.get(p));
            }
                
        }
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_43795939/article/details/114267734