5.18 二轮 并查集
This commit is contained in:
parent
69f8aa3fd1
commit
a900792e79
57
src/main/java/graph/CloneGraph.java
Normal file
57
src/main/java/graph/CloneGraph.java
Normal file
@ -0,0 +1,57 @@
|
||||
package graph;
|
||||
/**
|
||||
* 题目: 133. 克隆图 (cloneGraph)
|
||||
* 描述:给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。
|
||||
*
|
||||
* 图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])。
|
||||
*
|
||||
* class Node {
|
||||
* public int val;
|
||||
* public List<Node> neighbors;
|
||||
* }
|
||||
*
|
||||
* 差值是一个正数,其数值等于两值之差的绝对值。
|
||||
*
|
||||
示例 1:
|
||||
输入:adjList = [[2,4],[1,3],[2,4],[1,3]]
|
||||
输出:[[2,4],[1,3],[2,4],[1,3]]
|
||||
解释:
|
||||
图中有 4 个节点。
|
||||
节点 1 的值是 1,它有两个邻居:节点 2 和 4 。
|
||||
节点 2 的值是 2,它有两个邻居:节点 1 和 3 。
|
||||
节点 3 的值是 3,它有两个邻居:节点 2 和 4 。
|
||||
节点 4 的值是 4,它有两个邻居:节点 1 和 3 。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/clone-graph/
|
||||
*/
|
||||
//不会做
|
||||
import graph.Node;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CloneGraph {
|
||||
private HashMap<Node, Node> visited = new HashMap <> ();
|
||||
public Node cloneGraph(Node node) {
|
||||
if (node == null) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// 如果该节点已经被访问过了,则直接从哈希表中取出对应的克隆节点返回
|
||||
if (visited.containsKey(node)) {
|
||||
return visited.get(node);
|
||||
}
|
||||
|
||||
// 克隆节点,注意到为了深拷贝我们不会克隆它的邻居的列表
|
||||
Node cloneNode = new Node(node.val, new ArrayList());
|
||||
// 哈希表存储
|
||||
visited.put(node, cloneNode);
|
||||
|
||||
// 第一次 遇到某个邻居时,递归会深入——先把它自身拷贝出来(并加入 visited),再去拷贝它的邻居们……
|
||||
//如果再次遇到 同一个原节点(例如有环或多条路径到同一节点),就会走到第 2 步直接从 visited 里拿到已有的克隆节点,避免重复和死循环。
|
||||
for (Node neighbor: node.neighbors) {
|
||||
cloneNode.neighbors.add(cloneGraph(neighbor));
|
||||
}
|
||||
return cloneNode;
|
||||
}
|
||||
}
|
21
src/main/java/graph/Node.java
Normal file
21
src/main/java/graph/Node.java
Normal file
@ -0,0 +1,21 @@
|
||||
package graph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
32
src/main/java/union_find/CalcEquation.java
Normal file
32
src/main/java/union_find/CalcEquation.java
Normal file
@ -0,0 +1,32 @@
|
||||
package union_find;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 题目: 399. 除法求值 (calcEquation)
|
||||
* 描述:给你一个变量对数组 equations 和一个实数值数组 values 作为已知条件,其中 equations[i] = [Ai, Bi] 和 values[i] 共同表示等式 Ai / Bi = values[i] 。每个 Ai 或 Bi 是一个表示单个变量的字符串。
|
||||
*
|
||||
* 另有一些以数组 queries 表示的问题,其中 queries[j] = [Cj, Dj] 表示第 j 个问题,请你根据已知条件找出 Cj / Dj = ? 的结果作为答案。
|
||||
*
|
||||
* 返回 所有问题的答案 。如果存在某个无法确定的答案,则用 -1.0 替代这个答案。如果问题中出现了给定的已知条件中没有出现的字符串,也需要用 -1.0 替代这个答案。
|
||||
*
|
||||
* 注意:输入总是有效的。你可以假设除法运算中不会出现除数为 0 的情况,且不存在任何矛盾的结果。
|
||||
*
|
||||
* 注意:未在等式列表中出现的变量是未定义的,因此无法确定它们的答案。
|
||||
*
|
||||
示例 1:
|
||||
输入:equations = [["a","b"],["b","c"]], values = [2.0,3.0], queries = [["a","c"],["b","a"],["a","e"],["a","a"],["x","x"]]
|
||||
输出:[6.00000,0.50000,-1.00000,1.00000,-1.00000]
|
||||
解释:
|
||||
条件:a / b = 2.0, b / c = 3.0
|
||||
问题:a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
|
||||
结果:[6.0, 0.5, -1.0, 1.0, -1.0 ]
|
||||
注意:x 是未定义的 => -1.0
|
||||
|
||||
* 链接:https://leetcode.cn/problems/evaluate-division/
|
||||
*/
|
||||
public class CalcEquation {
|
||||
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
|
||||
return new double[1];
|
||||
}
|
||||
}
|
58
src/main/java/union_find/EquationsPossible.java
Normal file
58
src/main/java/union_find/EquationsPossible.java
Normal file
@ -0,0 +1,58 @@
|
||||
package union_find;
|
||||
/**
|
||||
* 题目: 990. 等式方程的可满足性 (equationsPossible)
|
||||
* 描述:给定一个由表示变量之间关系的字符串方程组成的数组,每个字符串方程 equations[i] 的长度为 4,并采用两种不同的形式之一:"a==b" 或 "a!=b"。在这里,a 和 b 是小写字母(不一定不同),表示单字母变量名。
|
||||
* 只有当可以将整数分配给变量名,以便满足所有给定的方程时才返回 true,否则返回 false。
|
||||
*
|
||||
示例 1:
|
||||
输入:["a==b","b!=a"]
|
||||
输出:false
|
||||
解释:如果我们指定,a = 1 且 b = 1,那么可以满足第一个方程,但无法满足第二个方程。没有办法分配变量同时满足这两个方程。
|
||||
|
||||
* 链接:https://leetcode.cn/problems/satisfiability-of-equality-equations/
|
||||
*/
|
||||
//并查集,第一次不会
|
||||
public class EquationsPossible {
|
||||
public boolean equationsPossible(String[] equations) {
|
||||
int[] parent = new int[26];
|
||||
for (int i = 0; i < 26; i++) {
|
||||
parent[i] = i;
|
||||
}
|
||||
for (String str : equations) {
|
||||
if (str.charAt(1) == '=') {
|
||||
int index1 = str.charAt(0) - 'a';
|
||||
int index2 = str.charAt(3) - 'a';
|
||||
union(parent, index1, index2);
|
||||
}
|
||||
}
|
||||
for (String str : equations) {
|
||||
if (str.charAt(1) == '!') {
|
||||
int index1 = str.charAt(0) - 'a';
|
||||
int index2 = str.charAt(3) - 'a';
|
||||
if (find(parent, index1) == find(parent, index2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//合并x,y所属的集合,这里没有做按秩合并,默认合到index2所在集合
|
||||
public void union(int[] parent, int index1, int index2) {
|
||||
// 先分别找到 index1 和 index2 的根节点,再把 root(index1) 的父指针指向 root(index2)
|
||||
parent[find(parent, index1)] = find(parent, index2);
|
||||
}
|
||||
//查找 index 元素所在集合的根节点(同时做路径压缩)
|
||||
public int find(int[] parent, int index) {
|
||||
// 当 parent[index] == index 时,说明已经是根节点
|
||||
while (parent[index] != index) {
|
||||
// 路径压缩:将当前节点直接挂到它父节点的父节点上
|
||||
// 这样可以让树变得更扁平,后续查找更快
|
||||
parent[index] = parent[parent[index]];
|
||||
// 跳到上一级,继续判断是否到根
|
||||
index = parent[index];
|
||||
}
|
||||
// 循环结束时,index 即为根节点下标
|
||||
return index;
|
||||
}
|
||||
|
||||
}
|
78
src/main/java/union_find/FindCircleNum.java
Normal file
78
src/main/java/union_find/FindCircleNum.java
Normal file
@ -0,0 +1,78 @@
|
||||
package union_find;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 题目: 547. 省份数量 (findCircleNum)
|
||||
* 描述:有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。
|
||||
* 省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。
|
||||
* 给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。
|
||||
* 返回矩阵中 省份 的数量。
|
||||
*
|
||||
示例 1:
|
||||
输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]]
|
||||
输出:2
|
||||
|
||||
* 链接:https://leetcode.cn/problems/number-of-provinces/
|
||||
*/
|
||||
public class FindCircleNum {
|
||||
//并查集
|
||||
int find(int[] parent ,int index){
|
||||
while (parent[index]!=index){
|
||||
parent[index]=parent[parent[index]];
|
||||
index=parent[index];
|
||||
}
|
||||
return index;
|
||||
}
|
||||
void union(int[] parent,int index1,int index2){
|
||||
parent[find(parent,index1)]=find(parent,index2);
|
||||
}
|
||||
public int findCircleNum(int[][] isConnected) {
|
||||
int res=0;
|
||||
int[]parent=new int[200];
|
||||
Set<Integer>set=new HashSet<>();
|
||||
for (int i = 0; i < 200; i++) {
|
||||
parent[i]=i;
|
||||
}
|
||||
int row=isConnected.length;
|
||||
for (int i = 0; i < row; i++) {
|
||||
for (int j = i+1; j < row; j++) {
|
||||
if(isConnected[i][j]==1)
|
||||
union(parent,i,j);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < isConnected.length; i++) {
|
||||
int father=find(parent,i);
|
||||
if(!set.contains(father)){
|
||||
res++;
|
||||
set.add(father);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
//深度优先搜索
|
||||
public int findCircleNum2(int[][] isConnected) {
|
||||
int cities = isConnected.length;
|
||||
boolean[] visited = new boolean[cities];
|
||||
int provinces = 0;
|
||||
for (int i = 0; i < cities; i++) {
|
||||
if (!visited[i]) {
|
||||
dfs(isConnected, visited, cities, i);
|
||||
provinces++;
|
||||
}
|
||||
}
|
||||
return provinces;
|
||||
}
|
||||
|
||||
public void dfs(int[][] isConnected, boolean[] visited, int cities, int i) {
|
||||
for (int j = 0; j < cities; j++) {
|
||||
if (isConnected[i][j] == 1 && !visited[j]) {
|
||||
visited[j] = true;
|
||||
dfs(isConnected, visited, cities, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user