算法训练营配套练习1,3
1.1并查集
1.2 优先队列
以前讲过,算法第四版的2-4
用Java写相关的话,在LC347题中,使用了下面的形式
class Solution {
public int[] topKFrequent(int[] nums, int k) {
int[] result=new int[k];
HashMap<Integer,Integer>map=new HashMap<>();
for(int n:nums){
map.put(n,map.getOrDefault(n,0)+1);
}
Set<Map.Entry<Integer,Integer>> entries=map.entrySet();
PriorityQueue<Map.Entry<Integer,Integer>> queue=new PriorityQueue<>((o1,o2)->o1.getValue()-o2.getValue());
for(Map.Entry<Integer,Integer> entry:entries){
queue.offer(entry);
if(queue.size()>k){
queue.poll();
}
}
for(int i=k-1;i>=0;i--){
result[i]=queue.poll().getKey();
}
return result;
}
}
首先先生成了一个HashMap
然后用put往HashMap里添加元素,此时用到了缺省的getOrDefault
然后把map转为一个set集合,便于后序的for循环提取
PriorityQueue<Map.Entry<Integer,Integer>> queue=new PriorityQueue<>((o1,o2)->o1.getValue()-o2.getValue());
一个小根堆的规范写法,右边是lambda表达式,左边装的是Map.Entry<Integer,Integer>
在java中队列的方法为offer(),poll(),size()
3.1字典树
以前讲过,算法第四版的5-2
推荐剑指offerII的62,63,
前缀树的真实实现是以数组形式,应该说是多个一维数组(可以是二维数组,也可以拿指针链起来)
0-25意味着a-z所有小写字母
我们可以看到tire[5][],tire[9][],tire[6][].里面都是没有值的。他们这个节点所代表的isEnd=true;
以上可以结合offerII的62题去理解。
3.2 AC自动机
好像要有点KMP和Trie的知识。不过整体流程还是容易的,代码不会写
视频流程
Build Trie就是普通的建一个Trie树
Get Fail是用BFS的格式走的,从上到下。他关注的是到目前这个单词的后缀,如果没相似的就指向root,有相同的后缀就指向上面那个相同后缀的节点
Match 首先你给一行字符串,肯定是有找不到的情况,直接指向最上面。然后就是根据我们的这些边和get fail做的边去移动,每一个红色节点都有回到root1的路径。每次经过红色节点,都要在左边的+1,表示有这个单词。
3.3后缀数组
后缀数组讲解
对于字符串s=“aabaaaab”
其后缀为
比如suffix[0]=“aabaaaab”,suffix[7]=“b”,suffix[5]=“aab”
然后对8个后缀进行以字符串为基础的排序
suffix[3]=“aaaab”
suffix[4]=“aaab”
suffix[5]=“aab”
suffix[0]=“aabaaaab”
suffix[6]=“ab”
suffix[1]=“abaaaab”
suffix[7]=“b”
suffix[2]=“baaaab”
则后缀数组为SA[]=[3,4,5,0,6,1,7,2]
排名数组就是SA反过来,rank[]=[4,6,8,1,2,3,5,7], 这边好像整体加一了
小事,我们重点是求SA[]
他这里一般用倍增算法
下面是流程,然后算的是rank,当rank不变的时候,就可以去转换为SA了
然后他嫌弃排序的时候复杂度高,就改用基数排序。不过得到的SA还是这个SA
最后说了一下LCP(最长公共前缀),利用LCP可以做很多事情,提了一个height数组,还有他的性质。我也不想看了,就这样吧。
后缀树组用于处理最长重复子串问题,比如LC第1044题
当然也可以处理不同子串的个数,最长回文子串,最长公共子串。