leetcode图
来源:互联网 发布:dnf台服数据库爆率修改 编辑:程序博客网 时间:2024/05/22 14:52
leetcode图的相关题目解析:
对图的遍历就是两个经典的方法DFS和BFS。BFS经常用Queue实现,DFS经常用递归实现(可改为栈实现)。
1、Clone Graph
题意:给定图中一个节点,克隆图
思路:用HashMap,key存lable值,value存新clone的node,用BFS方法遍历帮助拷贝neighbors的值。给定给一个节点,若lable在map中有,则表示已经clone;若没有,则将当前节点加入map中,一次clone节点的邻居节点。
代码:
class UndirectedGraphNode { int label; List<UndirectedGraphNode> neighbors; UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }}
private HashMap<Integer, UndirectedGraphNode> map = new HashMap<>(); public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { return clone(node); } private UndirectedGraphNode clone(UndirectedGraphNode node) { if (node == null) return null; if (map.containsKey(node.label)) { return map.get(node.label); } UndirectedGraphNode clone = new UndirectedGraphNode(node.label); map.put(clone.label, clone); for (UndirectedGraphNode neighbor : node.neighbors) { clone.neighbors.add(clone(neighbor)); } return clone; }
2、Evaluate Division
题意:以算式A / B = k的形式给出若干等式,其中A和B是以字符串表示的变量,k是实数(浮点数)。给定一些查询,返回结果。如果答案不存在,返回 -1.0
Given a / b = 2.0, b / c = 3.0.
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? .
return [6.0, 0.5, -1.0, 1.0, -1.0 ].
思路:输入等式可以看做一个有向图,例如等式a / b = 2.0,可以转化为两条边:
public double[] calcEquation(String[][] equations, double[] values, String[][] queries) { // build graph, use adjacent list map = new HashMap(); for(int i = 0; i < equations.length; i++) { String[] equation = equations[i]; if(!map.containsKey(equation[0])) map.put(equation[0], new ArrayList()); map.get(equation[0]).add(new Info(equation[1], values[i])); if(!map.containsKey(equation[1])) map.put(equation[1], new ArrayList()); map.get(equation[1]).add(new Info(equation[0], 1 / values[i])); } double[] result = new double[queries.length]; for(int i = 0; i < result.length; i++) { result[i] = find(queries[i][0], queries[i][1], 1, new HashSet()); } return result; } HashMap<String, List<Info>> map; private double find(String start, String end, double value, Set<String> visited) { if(visited.contains(start)) return -1; if(!map.containsKey(start)) return -1; if(start.equals(end)) return value; visited.add(start); for(Info next : map.get(start)) { double sub = find(next.den, end, value * next.val, visited); if(sub != -1.0) return sub; } visited.remove(start); return -1; } class Info { String den; double val; Info(String den, double val) { this.den = den; this.val = val; } }
3、题目:Reconstruct Itinerary
题意:tickets = [[“MUC”, “LHR”], [“JFK”, “MUC”], [“SFO”, “SJC”], [“LHR”, “SFO”]]
Return [“JFK”, “MUC”, “LHR”, “SFO”, “SJC”].
思路:存储在hash中,并且使用PriorityQueue来排序。等我们图建立好了以后,从节点JFK开始遍历,只要当前节点映射的multiset里有节点,我们取出这个节点,将其在multiset里删掉,然后继续递归遍历这个节点,由于题目中限定了一定会有解,那么等图中所有的multiset中都没有节点的时候,我们把当前节点存入结果中(头插形式),然后再一层层回溯回去。public List<String> findItinerary(String[][] tickets) { for (String[] ticket : tickets) targets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]); visit("JFK"); return route;}Map<String, PriorityQueue<String>> targets = new HashMap<>();List<String> route = new LinkedList();void visit(String airport) { while(targets.containsKey(airport) && !targets.get(airport).isEmpty()) visit(targets.get(airport).poll()); route.add(0, airport);}
4、Minimum Height Trees
题意:给定一系列边,寻找使得树高度最小的根节点
思路:从叶节点开始寻找,寻找离所有叶节点最远的节点,则为根。每次去掉当前图的所有叶子节点,重复此操作直到只剩下最后的根。
public List<Integer> findMinHeightTrees(int n, int[][] edges) { if (n == 1) return Collections.singletonList(0); //构建邻接表 List<Set<Integer>> adj = new ArrayList<>(n); for (int i = 0; i < n; ++i) adj.add(new HashSet<>()); for (int[] edge : edges) { adj.get(edge[0]).add(edge[1]); adj.get(edge[1]).add(edge[0]); } //找到所有叶子结点,所有入度(即相连边数)为 1 的节点即是叶子节点。 List<Integer> leaves = new ArrayList<>(); for (int i = 0; i < n; ++i) if (adj.get(i).size() == 1) leaves.add(i); //找高度最小的节点,即找离所有叶子节点最远的节点,也即找最中心的节点。 while (n > 2) { n -= leaves.size(); List<Integer> newLeaves = new ArrayList<>(); for (int i : leaves) { //每次去掉当前图的所有叶子节点,重复此操作直到只剩下最后的根。 int j = adj.get(i).iterator().next(); adj.get(j).remove(i); if (adj.get(j).size() == 1) newLeaves.add(j); } leaves = newLeaves; } return leaves; }
5、Course Schedule
题意:2, [[1,0],[0,1]],代表有两个课程,0的先行课是1,1的先行课的是0,不可能,输出false。
翻译:在一个有向图中,每次找到一个没有前驱节点的节点(也就是入度为0的节点),然后把它指向其他节点的边都去掉,重复这个过程(BFS),直到所有节点已被找到,或者没有符合条件的节点(如果图中有环存在)。
public boolean canFinish(int numCourses, int[][] prerequisites) { int[][] matrix = new int[numCourses][numCourses]; // i -> j int[] indegree = new int[numCourses]; for (int i=0; i<prerequisites.length; i++) { int ready = prerequisites[i][0]; int pre = prerequisites[i][1]; if (matrix[pre][ready] == 0) indegree[ready]++; //duplicate case matrix[pre][ready] = 1; } int count = 0; Queue<Integer> queue = new LinkedList(); for (int i=0; i<indegree.length; i++) { if (indegree[i] == 0) queue.offer(i); } while (!queue.isEmpty()) { int course = queue.poll(); count++; for (int i=0; i<numCourses; i++) { if (matrix[course][i] != 0) { if (--indegree[i] == 0) queue.offer(i); } } } return count == numCourses; }
- leetcode图
- LeetCode之克隆图
- LeetCode基础-图
- LeetCode基础-图-DFS
- LeetCode基础-图-BFS
- leetcode
- [leetcode]
- LeetCode
- leetcode
- leetcode
- leetcode:
- leetcode:
- LeetCode
- leetcode
- LEETCODE
- leetcode
- leetCode
- leetcode
- 使用notepad++开发python的配置——代码缩进、自动补齐、运行
- ADO.NET 主要的三个对象(SqlConnection/SqlCommand/SqlDataReader)
- Android自定义控件之循环旋转弧度不断变化圆弧的控件
- 【栈】洛谷 P1165 日志分析
- 题解_Automatic Judge
- leetcode图
- 【搜索】洛谷 P1164 小A点菜
- Android 备忘录 -- Menu
- 学习笔记---文件基础
- shell 编程
- AOP
- Naive Bayes贝叶斯
- 蓝桥杯 算法训练 字串统计 JAVA
- 【递推】洛谷 P1176 路径计数2