算法模板

一、基础算法

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;

 

posted @ 2022-01-16 14:32  没有你哪有我  阅读(41)  评论(0编辑  收藏  举报