mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7
115 字
1 分钟
Java 常用算法模板备忘整理
2026-06-04

归并排序#

// 归并排序数组的[l, r)区间
static void mergeSort(int[] arr, int l, int r) {
if (r - l <= 1) return; // 一直拆分到只剩最后一个元素
int mid = l + (r - l) / 2;
mergeSort(arr, l, mid); // 拆分左半边
mergeSort(arr, mid, r); // 拆分右半边
merge(arr, l, r); // 合并两边
}
static void merge(int[] arr, int l, int r) {
int[] tmp = new int[r - l];
int mid = l + (r - l) / 2;
int i = l, j = mid, k = 0;
while (i < mid && j < r) {
if (arr[i] < arr[j]) {
tmp[k++] = arr[i++];
} else {
tmp[k++] = arr[j++];
// 可选,累加逆序对数量
count += mid - i; // 左半边剩余元素与当前元素构成逆序对
}
}
// 补上剩余元素
while (i < mid) tmp[k++] = arr[i++];
while (j < r) tmp[k++] = arr[j++];
System.arraycopy(tmp, 0, arr, l, tmp.length);
}

质数筛#

埃氏筛#

boolean[] isPrime = new boolean[n + 1];
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= n; j += i) {
isPrime[j] = false;
}
}
}

欧拉筛#

boolean[] isPrime = new boolean[n + 1];
int[] primes = new int[n];
int count = 0;
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i <= n; i++) {
if (isPrime[i]) primes[count++] = i;
for (int j = 0; j < count && i * primes[j] <= n; j++) {
isPrime[i * primes[j]] = false;
if (i % primes[j] == 0) break;
}
}

快速幂#

// 快速计算a^b % MOD
static long fastPow(long a, long b, long MOD) {
long res = 1;
while (b > 0) {
if ((b & 1) == 1) {
res = res * a % MOD;
}
a = a * a % MOD;
b >>= 1;
}
return res;
}

费马小定理计算逆元#

前提条件:MOD 为质数,且 a 不被 MOD 整除

a 在模下的逆元为 a^(MOD - 2) % MOD

// 直接除法取模 b/a%MOD 会丢失精度,除以a等价于乘a在模下的逆元 => b * a^(MOD-2) % MOD
static long calc(long a, long MOD) {
return fastPow(a, MOD - 2, MOD); // 结果为逆元
}

最大公约数GCD和最小公倍数LCM#

static long gcd(long a, long b) {
if (b == 0) return a;
return gcd(b, a % b);
}
static long lcm(long a, long b) {
return a / gcd(a, b) * b; // 先除后乘防溢出
}

前缀和#

int[] sum = new int[n + 1];
for (int i = 0; i < n; i++) {
sum[i + 1] = sum[i] + arr[i];
}
// 求区间 [l, r] 的和
int rangeSum = sum[r] - sum[l - 1];

差分#

int[] diff = new int[n + 1];
diff[0] = arr[0];
// 构建差分数组
for (int i = 1; i < n; i++) {
diff[i] = arr[i] - arr[i - 1];
}
// 区间增值 [l, r] + val
void add(int l, int r, int val) {
diff[l] += val;
diff[r + 1] -= val;
}
// 还原数组
for (int i = 0; i < n; i++) {
if (i == 0) arr[i] = diff[i];
else arr[i] = arr[i - 1] + diff[i];
}

最小生成树#

Kruskal#

// edges: [u, v, w]
static int kruskal(int n, int[][] edges) {
Arrays.sort(edges, (a, b) -> a[2] - b[2]);
int sum = 0, count = 0;
for (int[] e : edges) {
// 根节点不同 => 不会连成环,可以合并
if (find(e[0]) != find(e[1])) {
union(e[0], e[1]);
sum += e[2];
if (++count == n - 1) break;
}
}
return count == n - 1 ? sum : -1;
}

并查集#

int[] p = new int[n + 1]; // 根节点负值取绝对值表示树高度
// 初始化每个节点都是根,初始高度为1
for (int i = 0; i <= n; i++) p[i] = -1;
// 查找根节点
static int find(int x) {
if (p[x] < 0) return x;
return p[x] = find(p[x]); // 扁平化子节点
}
// 合并
static void union(int x, int y) {
int rx = find(x);
int ry = find(y);
if (rx == ry) return;
if (p[rx] < p[ry]) {
p[ry] = rx;
} else if (p[rx] > p[ry]) {
p[rx] = ry;
} else {
p[rx] = ry;
p[ry]--; // 两树高度相同,合并高度+1(一个根指向另一个根)
}
}

Prim (优先队列 堆优化版 适合稀疏图)#

// g为邻接表 int[]为{v, w}
static int prim(List<int[]>[] g, int n) {
boolean[] visited = new boolean[n];
PriorityQueue<int[]> pq = new PriorityQueue<>((a,b) -> a[1] - b[1]);
pq.offer(new int[]{0, 0}); // 生成树起点
int sum = 0, count = 0;
while (!pq.isEmpty() && count < n) {
int[] cur = pq.poll();
int v = cur[0], w = cur[1];
if (visited[v]) continue;
visited[v] = true;
sum += w;
count++;
// 更新生成树周围
for (int[] e : g[v]) {
if (!visited[e[0]]) pq.offer(e);
}
}
return count == n ? sum : -1;
}

Prim (朴素版 适合稠密图)#

// g为邻接矩阵 int[n][n],不可达值设为 MAX_VALUE
static int prim(int[][] g, int n) {
boolean[] visited = new boolean[n];
int[] dist = new int[n]; // 当前生成树到各点的距离
Arrays.fill(dist, Integer.MAX_VALUE);
dist[0] = 0; // 生成树起点距离为0
int sum = 0;
for (int i = 0; i < n; i++) {
int u = -1, min = Integer.MAX_VALUE;
for (int j = 0; j < n; j++) {
if (!visited[j] && dist[j] < min) {
min = dist[j];
u = j;
}
}
if (u == -1) return -1;
// 找到了新的最近点,更新状态
visited[u] = true;
sum += dist[u];
// 更新生成树周围
for (int v = 0; v < n; v++) {
if (!visited[v] && g[u][v] < dist[v]) {
dist[v] = g[u][v];
}
}
}
return sum;
}

持续收集中…

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Java 常用算法模板备忘整理
http://mizuki.heycheems.top/posts/常用算法模板/
作者
heyCHEEMS
发布于
2026-06-04
许可协议
CC BY 4.0

部分信息可能已经过时

目录