一、基础算法
1、快排
1 public static void quickSort(int l, int r, int[] arr) {
2 if (l >= r) {
3 return;
4 }
5 int base = arr[(r - l) / 2 + l];
6 int i = l - 1, j = r + 1;
7 while (i < j) {
8 do i++; while (arr[i] < base);
9 do j--; while (arr[j] > base);
10 if (i < j) swap(i, j, arr);
11 }
12 quickSort(l, j, arr);
13 quickSort(j + 1, r, arr);
14 }
2、归并
1 public static void mergeSort(int l, int r, int[] arr) {
2 if (l >= r) {
3 return;
4 }
5 int mid = (l + r) / 2;
6 mergeSort(l, mid, arr);
7 mergeSort(mid + 1, r, arr);
8 int i = l, j = mid + 1, k = 0;
9 int[] tmp = new int[r - l + 1];
10 while (i <= mid && j <= r) {
11 if (arr[i] <= arr[j]) {
12 tmp[k++] = arr[i++];
13 } else {
14 tmp[k++] = arr[j++];
15 }
16 }
17 while (i <= mid) {
18 tmp[k++] = arr[i++];
19 }
20 while (j <= r) {
21 tmp[k++] = arr[j++];
22 }
23 // 最后将临时数组存储到arr中
24 for (int m = l, n = 0; m <= r; m++, n++) {
25 arr[m] = tmp[n];
26 }
27 }
3、整数二分
1 bool check(int x) {/* ... */} // 检查x是否满足某种性质
2
3 // 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
4 int bsearch_1(int l, int r)
5 {
6 while (l < r)
7 {
8 int mid = l + r >> 1;
9 if (check(mid)) r = mid; // check()判断mid是否满足性质
10 else l = mid + 1;
11 }
12 return l;
13 }
14 // 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
15 int bsearch_2(int l, int r)
16 {
17 while (l < r)
18 {
19 int mid = l + r + 1 >> 1;
20 if (check(mid)) l = mid;
21 else r = mid - 1;
22 }
23 return l;
24 }
4、高精度加法
1 public static List<Integer> add(List<Integer> v1, List<Integer> v2) {
2 List<Integer> v3 = new ArrayList<>();
3 // 进位
4 int t = 0;
5 for (int i = 0, j = 0; i < v1.size() || j < v2.size(); i++, j++) {
6 if (i < v1.size() && v1.get(i) > 0) {
7 t += v1.get(i);
8 }
9 if (j < v2.size() && v2.get(j) > 0) {
10 t += v2.get(j);
11 }
12 v3.add(t % 10);
13 // 更新t
14 t /= 10;
15 }
16 if (t > 0) {
17 v3.add(1);
18 }
19 return v3;
20 }
5、高精度减法
1 public static List<Integer> sub(List<Integer> v1, List<Integer> v2) {
2 // v1 >= v2
3 List<Integer> v3 = new ArrayList<>();
4 // t是借位,要么为0、要么为1
5 int t = 0;
6 for (int i = 0; i < v1.size(); i++) {
7 // 先处理借位
8 t = v1.get(i) - t;
9 if (i < v2.size()) t -= v2.get(i);
10 v3.add((t + 10) % 10);
11 if (t < 0) {
12 t = 1;
13 } else {
14 t = 0;
15 }
16 }
17 // 处理前导0,可能会有多个前导,所以这里用while比较保险
18 while (v3.size() > 1 && v3.get(v3.size() - 1) == 0) {
19 v3.remove(v3.size() - 1);
20 }
21 return v3;
22 }
23
24 public static boolean compare(List<Integer> v1, List<Integer> v2) {
25 if (v1 == null) return false;
26 if (v2 == null) return true;
27 if (v1.size() > v2.size()) return true;
28 if (v1.size() < v2.size()) return false;
29 // 长度相等,比较每一位
30 // 从最高位开始比较
31 for (int i = v1.size() - 1; i >= 0; --i) {
32 if (v1.get(i) > v2.get(i)) {
33 return true;
34 } else if (v1.get(i) < v2.get(i)) {
35 return false;
36 }
37 }
38 return true;
39 }
6、高精度乘法
1 public static List<Integer> mul(List<Integer> v1, int b) {
2 List<Integer> v3 = new ArrayList<>();
3 int t = 0;
4 for (int i = 0; i < v1.size() || t > 0; i++) {
5 if (i < v1.size()) t += v1.get(i) * b;
6 v3.add(t % 10);
7 t /= 10;
8 }
9 while (v3.size() > 1 && v3.get(v3.size() - 1) == 0) {
10 v3.remove(v3.size() - 1);
11 }
12 return v3;
13 }
7、高精度除法
1 public static List<Integer> div(List<Integer> v1, int b) {
2 List<Integer> v3 = new ArrayList<>();
3 // t代表余数
4 int t = 0;
5 // 反着做,保证加减乘除的模板都通用
6 for (int i = v1.size() - 1; i >= 0; i--) {
7 t = t * 10 + v1.get(i);
8 v3.add(t / b);
9 t %= b;
10 }
11 // 取反
12 Collections.reverse(v3);
13 // 取出前导零
14 while (v3.size() > 1 && v3.get(v3.size() - 1) == 0) {
15 v3.remove(v3.size() - 1);
16 }
17 return v3;
18 }
8、一维差分
1 public static void insert(int l, int r, int c) {
2 // 在[l, r]区间上给每个数加上c
3 b[l] += c;
4 b[r + 1] -= c;
5 }
9、二维差分
1 b[x1][y1] += c;
2 b[x2 + 1][y1] -= c;
3 b[x1][y2 + 1] -= c;
4 b[x2 + 1][y2 + 1] += c;