图与搜索

主要知识点:

克隆图

拓扑排序

DFS BFS

BFS两个使用场景:图的遍历 简单图求最短路径

BFS in Graph 和BFS in Tree的主要区别就是有无环

Clone Graph --not bug free

方法一:递归

 1 public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         // write your code here
 3         if (node == null) {
 4             return node;
 5         }
 6         HashMap<UndirectedGraphNode, UndirectedGraphNode> hashMap = new HashMap<>();
 7         return help(node, hashMap);
 8     }
 9
10     public UndirectedGraphNode help(UndirectedGraphNode node, HashMap<UndirectedGraphNode, UndirectedGraphNode> hashMap) {
11         UndirectedGraphNode root = new UndirectedGraphNode(node.label);
12         hashMap.put(node, root);
13         for (UndirectedGraphNode neighbor : node.neighbors) {
14             if (hashMap.containsKey(neighbor)) {
15                 root.neighbors.add(hashMap.get(neighbor));
16             } else {
17                 root.neighbors.add(help(neighbor, hashMap));
18             }
19         }
20         return root;
21     }

方法二:非递归,分两步:找节点和mapping  neighbors

 1 public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
 2         // write your code here
 3         if (node == null) {
 4             return node;
 5         }
 6         //getNodeAndMapping
 7         List<UndirectedGraphNode> nodes = new ArrayList<UndirectedGraphNode>();
 8         HashMap<UndirectedGraphNode, UndirectedGraphNode> mapping = new HashMap<>();
 9         Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
10         queue.offer(node);
11         nodes.add(node);
12         mapping.put(node, new UndirectedGraphNode(node.label));
13         while (!queue.isEmpty()) {
14             UndirectedGraphNode cur = queue.poll();
15             for (UndirectedGraphNode neighbor : cur.neighbors) {
16                 if (mapping.containsKey(neighbor)) {
17                     continue;
18                 }
19                 nodes.add(neighbor);
20                 mapping.put(neighbor, new UndirectedGraphNode(neighbor.label));
21                 queue.offer(neighbor);
22             }
23         }
24
25         //clone neighbor
26         for (UndirectedGraphNode old : nodes) {
27             UndirectedGraphNode newNode = mapping.get(old);
28             for (UndirectedGraphNode neighbor : old.neighbors) {
29                 newNode.neighbors.add(mapping.get(neighbor));
30             }
31         }
32         return mapping.get(node);
33     }

Topological Sorting

 1 public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
 2         // write your code here
 3         Map<DirectedGraphNode, Integer> indegreeMap = new HashMap<DirectedGraphNode, Integer>();
 4         getInDegree(graph, indegreeMap);
 5         Queue<DirectedGraphNode> queue = new LinkedList<DirectedGraphNode>();
 6         for (DirectedGraphNode node : graph) {
 7             if (!indegreeMap.containsKey(node)) {
 8                 queue.offer(node);
 9             }
10         }
11         ArrayList<DirectedGraphNode> result = new ArrayList<>();
12         while (!queue.isEmpty()) {
13             DirectedGraphNode cur = queue.poll();
14             result.add(cur);
15             for (DirectedGraphNode neighbor : cur.neighbors) {
16                 int indegree = indegreeMap.get(neighbor);
17                 indegreeMap.put(neighbor, indegree - 1);
18                 if (indegree == 1) {
19                     queue.offer(neighbor);
20                 }
21             }
22         }
23         return result;
24     }
25
26     public void getInDegree(ArrayList<DirectedGraphNode> graph,
27         Map<DirectedGraphNode, Integer> indegreeMap) {
28             for (DirectedGraphNode node : graph) {
29                 for (DirectedGraphNode neighbor : node.neighbors) {
30                     if (!indegreeMap.containsKey(neighbor)) {
31                         indegreeMap.put(neighbor, 1);
32                     } else {
33                         indegreeMap.put(neighbor, indegreeMap.get(neighbor) + 1);
34                     }
35                 }
36             }
37     }

Permutations

Given a list of numbers, return all possible permutations.You can assume that there is no duplicate numbers in the list.

 1  public List<List<Integer>> permute(int[] nums) {
 2         // write your code here
 3         List<List<Integer>> results = new ArrayList<>();
 4         if (nums == null || nums.length == 0) {
 5             results.add(new ArrayList<Integer>());
 6             return results;
 7         }
 8         boolean[] used = new boolean[nums.length];
 9         BFS(nums, results, new ArrayList<Integer>(), used);
10         return results;
11     }
12
13     public void BFS(int[] nums, List<List<Integer>> results, List<Integer> cur, boolean[] used) {
14         if (cur.size() == nums.length) {
15             results.add(new ArrayList<>(cur));
16             return ;
17         }
18         for (int i = 0; i < nums.length; i++) {
19             if (used[i]) {
20                 continue;
21             }
22             used[i] = true;
23             cur.add(nums[i]);
24             BFS(nums, results, cur, used);
25             cur.remove(cur.size() - 1);
26             used[i] = false;
27         }
28     }

Permutations II

注意不要忘了排序。

Given a list of numbers with duplicate number in it. Find all unique permutations.

 1 public List<List<Integer>> permuteUnique(int[] nums) {
 2         // write your code here
 3         List<List<Integer>> results = new ArrayList<>();
 4         if (nums == null || nums.length == 0) {
 5             results.add(new ArrayList<Integer>());
 6             return results;
 7         }
 8         Arrays.sort(nums);//Attention!
 9         boolean[] used = new boolean[nums.length];
10         BFS(nums, results, new ArrayList<Integer>(), used);
11         return results;
12     }
13
14     public void BFS(int[] nums, List<List<Integer>> results, List<Integer> cur, boolean[] used) {
15         if (cur.size() == nums.length) {
16             results.add(new ArrayList<>(cur));
17             return ;
18         }
19         for (int i = 0; i < nums.length; i++) {
20             if (used[i]) {
21                 continue;
22             }
23             if (i > 0 && !used[i - 1] && nums[i] == nums[i - 1]) {
24                 continue;
25             }
26             used[i] = true;
27             cur.add(nums[i]);
28             BFS(nums, results, cur, used);
29             cur.remove(cur.size() - 1);
30             used[i] = false;
31         }
32     }

时间: 2024-10-12 20:19:17

图与搜索的相关文章

算法导论 第二十二章:图的搜索

图有两种标准的表示方法,即邻接矩阵和邻接表(通常邻接矩阵用于稠密图,邻接表用于稀疏图).如下: 对于图的搜索有两种方法:深度优先搜索 & 广度优先搜索. 广度优先搜索(Breadth-first search) 广度优先搜索是将已发现和未发现顶点之间的边界沿其广度方向向外扩展.亦即算法首先会发现和s距离为k的所有点,然后才会发现和s距离为k+1的其他顶点. 伪代码: EG: 运行时间:O(V+E). 深度优先遍历(Depth-first search) 在深度优先搜索中,对于最新发现的顶点,如果

Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离

Dijkstra 算法,用于对有权图进行搜索,找出图中两点的最短距离,既不是DFS搜索,也不是BFS搜索. 把Dijkstra 算法应用于无权图,或者所有边的权都相等的图,Dijkstra 算法等同于BFS搜索. http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 2.算法描述 1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源

查找二 树与图的搜索

搜索对象是一个数据的集合(称为搜索表),除了执行搜索外,还可能执行其他操作,例如添加新元素,这样可能会改变搜索表的结构.因此,搜索表可以区分为静态搜索表(表的结构不发生改变)和动态搜索表两种情况. 常见的适用于静态搜索表的搜索方法有:顺序搜索.折半搜索.Fibonacci搜索等. 适用于动态搜索表的搜索方法有:二叉排序算法,平衡二叉搜索算法. 二叉排序树搜索 二叉排序树(Binary sort Tree,BST)又称为二叉查找(搜索)树(Binary Search Tree) .其必须为二叉排序

[Algorithms]图的搜索

未完待续 知道图的存储,DFS,BFS 二分图判定 1 //二分图判定 2 //给定一个有n个顶点的图,给图上每个顶点染色,要使相邻顶点颜色不同,是否能用最多2种颜色染色?无重边和自环. 3 //只用两种颜色,确定一个顶点的颜色后,和它相邻的顶点的颜色随之确定的那个. 4 //选择任意一个顶点出发,依次确定相邻顶点的颜色,判断是否可被2种颜色染色,深度优先搜索 5 6 //输入 7 vector<int> G[MAX_V];//图 8 int V; //顶点数 9 int color[MAX_

二分图判定【图的搜索】

二分图判定 给定一个图,要给图上每个顶点染色,并且要使得相邻的顶点颜色不同.问是否能最多用2种颜色进行染色? 参考如下: Source Code: #include <iostream> #include <vector> using namespace std; vector<int> Edge[1010]; int colorArr[1010]; void initColorArr(int length){ for(int i=0;i<=length;++i)

图的搜索---二分图判定

/** 二分图判定 图的着色问题,最小着色数为二的图 DFS */ #include "cstdio" #include "cstring" #include "cstdlib" #include "vector" #define MAX 1002 std::vector<int> G[MAX]; int color[MAX]; int n; bool dfs(int x,int c) { color[x]=c;

AOJ894 种花【图的搜索+回溯】

题面: 花老师有一个农场,农场的花一共有 4 种颜色, 花老师不喜欢老旧的东西,所以,她希望每天种花的方案都不一样.特别地,她也觉得两种一样颜色的花种在相邻的位置会很无聊.现在,她想知道,一共有多少种花的方案.这里要注意的是,农场的种花的位置是不规则的.因此我们给出一对一对的相邻的位置的关系. Input 第一行两个数 N 和 M,表示种花的位置的个数和相邻的位置的对数 接下来 M 行,每行一组数 A, B 表示 A, B 相邻 Output 一个数表示染色方法数 Sample Input 5

二分图判断 (图的搜索)

二分图,又叫做双分图 二部图 偶图,指顶点可以分成两个不相交的集U和V,使得在同一个集内的顶点不相邻(没有共同边)的图. 无向图G为二分图的充要条件是,G至少有两个顶点,且其所有回路的长度均为偶数. 给定一个具有N个顶点的图,判断其是不是二分图(如着色问题,最小着色数为2的图就是二分图),可以用DFS处理.选择任意一个顶点出发,依次确定相邻顶点的颜色,就可以判断是否可以被2种颜色染色了. 代码如下 #include <cstdio> #include <cstring> #incl

奇妙的棋盘(建图+神仙搜索)

数据 题目大意: 已经很简洁了 题解: 把原图中相同颜色且相邻的点缩成一个点 若在原图中,两个不同颜色的联通块有边重合 代表可以花费1的代价使得两个联通块颜色一样 枚举第一个操作的点,则在新图中以它为起点的最长路径就是当前答案 注意,如果终点是黑点,答案要加1 \[O((n*m)^2)\] AC代码 #include <cstdio> #include <queue> #include <map> using namespace std; const int dx[4]