当前位置: 首页 > news >正文

算法模板(Java版)_字符串、并查集和堆

@ZZHow(ZZHow1024)

字符串

KMP字符串

致敬三位前辈:D.E.Knuth、J.H.Morris 和 V.R.Pratt!

字符串模式匹配算法,大大避免重复遍历的情况,克努特-莫里斯-普拉特算法。

  • 例题:AcWing 831. KMP字符串
import java.io.*;
import java.util.*;public class Main {static final int N = 100010;static final int M = 1000010;static char[] p = new char[N];static char[] s = new char[M];static int[] ne = new int[N];public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));int n = Integer.parseInt(br.readLine());String pStr = " " + br.readLine();int m = Integer.parseInt(br.readLine());String sStr = " " + br.readLine();p = pStr.toCharArray();s = sStr.toCharArray();// 计算 next 数组for (int i = 2, j = 0; i <= n; i++) {while (j != 0 && p[i] != p[j + 1])j = ne[j];if (p[i] == p[j + 1])j++;ne[i] = j;}// KMP 匹配for (int i = 1, j = 0; i <= m; i++) {while (j != 0 && s[i] != p[j + 1])j = ne[j];if (s[i] == p[j + 1])j++;if (j == n) {bw.write((i - n) + " ");j = ne[j];}}br.close();bw.close();}
}

Trie树

用于高效地存储和查找字符串集合的数据结构。

  • 例题:AcWing 835. Trie字符串统计
import java.io.*;
import java.util.*;public class Main {static final int N = 100010;static int[][] son = new int[N][26]; // 存储所有节点的儿子是什么static int[] cnt = new int[N]; // 字符串结束标记且进行计数static int idx; // 下标为 0 的点,既是跟节点,又是空节点public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));int n = Integer.parseInt(br.readLine());while (n-- != 0) {String[] lines = br.readLine().split(" ");char op = lines[0].charAt(0);String str = lines[1];switch (op) {case 'I': {insert(str.toCharArray());break;}case 'Q': {bw.write(query(str.toCharArray()) + "");bw.newLine();}}}br.close();bw.close();}// 插入字符串public static void insert(char[] str) {int p = 0;for (int i = 0; i < str.length; i++) {int u = str[i] - 'a';if (son[p][u] == 0)son[p][u] = ++idx;p = son[p][u];}cnt[p]++;}// 查询字符串出现的次数public static int query(char[] str) {int p = 0;for (int i = 0; i < str.length; i++) {int u = str[i] - 'a';if (son[p][u] == 0)return 0;p = son[p][u];}return cnt[p];}
}

并查集

两个操作:

  1. 将两个集合合并。
  2. 询问两个元素是否在一个集合当中。

基本原理:每个集合用一棵树来表示。树根的编号就是整个集合的编号。每个节点存储
它的父节点,P[x] 表示 x 的父节点。

问题 1:如何判断树根 if (p[x] == ×) {return true;}
问题 2:如何求 x 的集合编号 while (p[x] != x) x = p[x];
问题 3:如何合并两个集合,p[x] 是 x 的集合编号,p[y] 是 y 的集合编号 p[x] = y;

  • 例题:AcWing 836. 合并集合
import java.util.Scanner;public class Main {static int[] p;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();p = new int[n + 10];for (int i = 1; i <= n; i++)p[i] = i;int m = scanner.nextInt();while (m-- != 0) {char op = scanner.next().charAt(0);int a = scanner.nextInt();int b = scanner.nextInt();switch (op) {case 'M': {p[find(a)] = find(b);break;}case 'Q': {System.out.println((find(a) == find(b)) ? "Yes" : "No");break;}}}}// 返回祖宗节点 + 路径压缩public static int find(int x) {if (x != p[x])p[x] = find(p[x]);return p[x];}
}

手写堆,功能:

  1. 插入一个数:heap[++size] = x; up(size);
  2. 求集合中的最小值:heap[1];
  3. 删除最小值:heap[1] = heap[size]; size--; down(1);
  4. 删除任意一个元素:heap[1] = heap[k]; size--; down(1); up(1);
  5. 修改任意一个元素:heap[k] = x; down(k); up(k);

使用一维数组存储:

  • x 左儿子:2x
  • x 右儿子:2x + 1
  • 例题:AcWing 839. 模拟堆
import java.util.Scanner;public class Main {static final int N = 100010;static int[] h;static int[] ph;static int[] hp;static int size;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();h = new int[n + 10];ph = new int[n + 10];hp = new int[n + 10];int m = 0;while (n-- != 0) {String op = scanner.next();switch (op) {case "I": {int x = scanner.nextInt();size++;m++;ph[m] = size;hp[size] = m;h[size] = x;up(size);break;}case "PM": {System.out.println(h[1]);break;}case "DM": {heapSwap(1, size);size--;down(1);break;}case "D": {int k = scanner.nextInt();k = ph[k];heapSwap(k, size);size--;down(k);up(k);break;}case "C": {int k = scanner.nextInt();int x = scanner.nextInt();k = ph[k];h[k] = x;down(k);up(k);break;}}}}public static void heapSwap(int a, int b) {int temp = ph[hp[a]];ph[hp[a]] = ph[hp[b]];ph[hp[b]] = temp;temp = hp[a];hp[a] = hp[b];hp[b] = temp;temp = h[a];h[a] = h[b];h[b] = temp;}public static void up(int u) {while (u / 2 != 0 && h[u / 2] > h[u]) {heapSwap(u / 2, u);u /= 2;}}public static void down(int u) {int t = u; // t 表示三个节点中最小节点的编号if (u * 2 <= size && h[u * 2] < h[t])t = u * 2;if (u * 2 + 1 <= size && h[u * 2 + 1] < h[t])t = u * 2 + 1;if (u != t) {heapSwap(u, t);down(t);}}
}

文章转载自:

http://jBcw4afg.tkhyk.cn
http://xnXPIgWC.tkhyk.cn
http://F5TFVg9a.tkhyk.cn
http://fu9nCLra.tkhyk.cn
http://hAdu2I5b.tkhyk.cn
http://AafsPXAN.tkhyk.cn
http://AAKLlcOh.tkhyk.cn
http://YFBI750K.tkhyk.cn
http://cgT5PBNh.tkhyk.cn
http://uc7mDTYE.tkhyk.cn
http://CvhqqRUW.tkhyk.cn
http://PyJnmHLJ.tkhyk.cn
http://fibmdUwd.tkhyk.cn
http://MNEWKxK5.tkhyk.cn
http://HEeB5Ke5.tkhyk.cn
http://v8Dmy9rr.tkhyk.cn
http://EwbS2c0C.tkhyk.cn
http://lyqhA3JH.tkhyk.cn
http://tb6jKe0S.tkhyk.cn
http://7Fe7oZDL.tkhyk.cn
http://Amu1M9xG.tkhyk.cn
http://XZcC3LCT.tkhyk.cn
http://FjpCeiC7.tkhyk.cn
http://1xsZ82ay.tkhyk.cn
http://3s4ayanz.tkhyk.cn
http://kx8vCDrN.tkhyk.cn
http://zxXSJuUa.tkhyk.cn
http://HK0P8wJ0.tkhyk.cn
http://jbqYXBJz.tkhyk.cn
http://Om63vpVC.tkhyk.cn
http://www.dtcms.com/a/366218.html

相关文章:

  • 云数据库服务(参考自腾讯云计算工程师认证课程)更新中......
  • 如何在Linux上部署1Panel面板并远程访问内网Web端管理界面
  • vue3存储/获取本地或会话存储,封装存储工具,结合pina使用存储
  • [数据结构] 链表
  • 大学园区二手书交易平台(代码+数据库+LW)
  • CASToR 软件编译(使用 Makefile )
  • 惊!printf 不往屏幕输?都是 fd 在搞鬼!爆肝拆解 Linux 文件描述符 + 重定向底层,学会直接在终端横着走
  • NIPT 的时点选择与胎儿的异常判定
  • Spring Boot 启动卡死:循环依赖与Bean初始化的深度分析
  • Web与Nginx网站服务
  • 如何导出 手机中的APK并查看清单文件
  • 《R for Data Science (2e)》免费中文翻译 (第7章) --- Data import(1)
  • 2025高教社杯国赛数学建模选题建议+初步分析
  • 企业微信SCRM工具推荐:微盛AI·企微管家为什么是首选?
  • 直接让前端请求代理到自己的本地服务器,告别CV报文到自己的API工具,解放双手
  • 国产化Excel处理组件Spire.XLS教程:Java 向 Excel 写入数据的3种高效方法(含代码示例)
  • 8051单片机-成为点灯大师
  • 单片机实现分页显示环形更新的历史数据
  • 详细讲解pyspark中dsl格式进行大数据开发中的的所有编程情况
  • 大数据毕业设计选题推荐-基于大数据的懂车帝二手车数据分析系统-Spark-Hadoop-Bigdata
  • uni 拍照上传拍视频上传以及相册
  • React 中的 HOC 和 Hooks
  • 大数据毕业设计选题推荐-基于大数据的儿童出生体重和妊娠期数据可视化分析系统-Hadoop-Spark-数据可视化-BigData
  • 【C++练习】06.输出100以内的所有素数
  • 结合prompt源码分析NodeRAG的build过程
  • 【C++闯关笔记】STL:list 的学习和使用
  • 解密大语言模型推理:Prompt Processing 的内存管理与计算优化
  • Redis vs Memcached vs MongoDB:深入对比与选型指南
  • C# 修改基类List中某一元素的子类类型
  • 如何在 iPhone 或 iPad 上删除文件