133. Clone Graph
我们也可以使用 BFS 来遍历图,使用队列 queue 进行辅助,还是需要一个 HashMap 来建立原图结点和克隆结点之间的映射。先克隆当前结点,然后建立映射,并加入 queue 中,进行 while 循环。在循环中,取出队首结点,遍历其所有 neighbor 结点,若不在 HashMap 中,我们根据 neigbor 结点值克隆一个新 neighbor 结点,建立映射,并且排入 queue 中。然后将 neighbor 结点在 HashMap 中的映射结点加入到克隆结点的 neighbors 数组中即可
Map.containsKey() :是否含有key
Map.get(key) : 获取key对应的value
class Solution {
public Node cloneGraph(Node node) {
if(node == null) return null;
Map<Node, Node> map = new HashMap<>();
Node newNode = new Node(node.val, new ArrayList<>());
map.put(node, newNode); Queue<Node> queue = new LinkedList<>();
queue.add(node);
while(!queue.isEmpty()){
Node cur = queue.poll();
for(Node nei : cur.neighbors){
if(!map.containsKey(nei)){
map.put(nei, new Node(nei.val, new ArrayList<>()));
queue.add(nei);
}
map.get(cur).neighbors.add(map.get(nei));
}
}
return newNode;
}
}
399. Evaluate Division
用有向图的方法做,先存入图中,再用DFS遍历。
Map.keySet() : 获取map对应的所有的key值。
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
Map<String, Map<String, Double>> g = new HashMap<>();
buildGraph(g, equations, values); double[] res = new double[queries.size()];
Arrays.fill(res, -1.0);
int index = 0;
for(List<String> q : queries){
String a = q.get(0);
String b = q.get(1); if(!g.containsKey(a) || !g.containsKey(b)){
index++;
continue;
}else{
dfs(g, a, b, res, index, new HashSet<>(), 1.0);
index++;
}
}
return res;
} private void dfs(Map<String, Map<String, Double>> g, String a, String b, double[] res,
int index, Set<String> visited, double tmp){
visited.add(a); if(g.get(a) == null || g.get(a).size() == 0){
return;
}
if(g.get(a).containsKey(b)){
res[index] = g.get(a).get(b) * tmp;
return;
} for(String next : g.get(a).keySet()){
if(visited.contains(next)) continue;
dfs(g, next, b, res, index, visited, g.get(a).get(next)*tmp);
}
} private void buildGraph(Map<String, Map<String, Double>> g, List<List<String>> equations, double[] values){
int index = 0;
for(List<String> e : equations){
String a = e.get(0);
String b = e.get(1);
g.putIfAbsent(a, new HashMap<>());
g.putIfAbsent(b, new HashMap<>());
g.get(a).put(b, values[index]);
g.get(b).put(a, 1.0 / values[index]);
index++;
g.get(a).put(a, 1.0);
g.get(b).put(b, 1.0);
}
}
}
223. Rectangle Area
尝试先找出所有的不相交的情况,只有四种,一个矩形在另一个的上下左右四个位置不重叠,这四种情况下返回两个矩形面积之和。其他所有情况下两个矩形是有交集的,这时候只要算出长和宽,即可求出交集区域的大小,然后从两个矩型面积之和中减去交集面积就是最终答案。求交集区域的长和宽也不难,由于交集都是在中间,所以横边的左端点是两个矩形左顶点横坐标的较大值,右端点是两个矩形右顶点的较小值,同理,竖边的下端点是两个矩形下顶点纵坐标的较大值,上端点是两个矩形上顶点纵坐标的较小值。之前是可以直接将 sum1 和 sum2 加起来的,可以后来OJ搞了些恶心的 test case,使得直接把 sum1 和 sum2 相加会溢出,所以只好分开了,若两个矩形有重叠,那么返回的时候也不能让 sum1 和 sum2 直接相加,中间一定要先减去重叠部分才行
class Solution {
public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
int sum1 = (C - A) * (D - B), sum2 = (H - F) * (G - E);
if(E >= C || F >= D || B >= H || A >= G) return sum1 + sum2;
return sum1 - (Math.min(G, C) - Math.max(A, E)) * (Math.min(D, H) - Math.max(B, F)) + sum2;
}
}