岛
只分析多线程下如何优化。
假设把矩阵分成两块,交给两个线程去处理。那么各自跑完会在地图上标注**当前的1属于哪个中心点(多线程间全局变量可以使用volatile关键字)
先站在左边一方的角度考虑,只需要把边界上的1,即图上的A位置。接着向右边进行询问,由于右边的格子上是1,那么就把AC进行合并(使用并查集进行优化),岛的数量-1。 下一次遇到AC的时候,并查集查询到属于同一个集合,那么就不进行操作。
总结一下,
第一步:进行区域划分,交给不同的线程去执行dfs,并且标注扩散源,得到初始tot岛数量。
第二步:针对边界进行合并,合并通过并查集。合并两个区域就让tot-1。
并查集代码
import java.util.HashMap;
import java.util.List;
public class UnionFindSet {
static class Node{
}
public HashMap<Node,Node> fatherMap;
public HashMap<Node,Integer> sizeMap;
public UnionFindSet(List<Node>list){
makeSets(list);
}
private void makeSets(List<Node> list) {
fatherMap.clear();
sizeMap.clear();
for(Node node:list){
fatherMap.put(node,node);
sizeMap.put(node,1);
}
}
Node findHead(Node node){
while (fatherMap.get(node) != node){
node = fatherMap.get(node);
}
return node;
}
public boolean isSameSet(Node a, Node b){
return findHead(a) == findHead(b);
}
public void union(Node a,Node b){
if(a == null || b == null)
return;
Node aHead = findHead(a);
Node bHead = findHead(b);
if (aHead != bHead) {
int aSetSize= sizeMap.get(aHead);
int bSetSize = sizeMap.get(bHead);
if (aSetSize <= bSetSize) {
fatherMap.put(aHead, bHead);
sizeMap.put(bHead, aSetSize + bSetSize);
} else {
fatherMap.put(bHead, aHead);
sizeMap.put(aHead, aSetSize + bSetSize);
}
}
}
}
前缀树
https://blog.youkuaiyun.com/qq_37591656/article/details/87896097#comments 牛客网的项目总结中已经有源代码,这里就当复习。
1、数据结构
class TrieNode{
// 根节点,前缀树的入口,val为空
private TrieNode rootNode = new TrieNode();
// 根节点的子结点们
private Map<Character, TrieNode> subNodes = new HashMap<>();
// 结束标志
int end;
// 前缀数量,用于删除
int path;
}
2、插入(String word)
从根节点root = rootNode出发,遍历word的每个字符,如果root的子节点中包含了当前字符,那么root = root.subNodes.get© ; 否则在root下新建一个TrieNode。经过每个结点时 root.path++,为了方便后面的删除
3、查询(String word)
从根节点root = rootNode出发,指针p1、p2初始化时都指向word的起点。当p2所指的位置在root的subNode中存在,就询问end是否为1,如果是1标明找到,递推到下一轮;如果root中的end==0,那么进行下一层查找,p2++, root = root.subNode.get(word[ p2 ])。 当root的subNodes不存在p2,那么查找失败,p1++,p2++, root = rootNode。
4、删除(String word)
从根节点开始查找word,每个结点的root.path–; 当遇到root.path减完==0,直接把root.subsNode.put(c,null);后面的直接可以删除