算法(keep learning)

基础算法

背模板加刷题

排序

快排

主要思想:分治

  • 第一步:确认一个分界点,比如起点,中间点(分界点),末点

  • 第二步:调整区间,使得第一个区间的数都小于等于分界点,第二个区间都大于分界点

  • 递归处理左右两端

    private static int[] quickSort(int[] arr, int left, int right) {
    // 递归终止条件,如果左边界大于等于右边界则认为递归结束
    if (left >= right) {
    return arr;
    }
    // 设定一个分界值,这里是(left + right)/ 2
    int p = arr[left + right >> 1];
    // 左右提前预留一个位置
    int i = left - 1;
    int j = right + 1;
    while (i < j) {
    // 等效于do while
    // 当数值小于分界值时持续遍历,直到找到第一个大于等于分界值的索引
    // 如果是逆序则调整两个while循环
    while (arr[++i] < p)
    ;
    while (arr[--j] > p)
    ;
    // 交换左右两侧不符合预期的数值
    if (i < j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    }
    }
    // 由于分界值取的是left + right >> 1,因此递归取的是left,j j + 1,right
    quickSort(arr, left, j);
    quickSort(arr, j + 1, right);
    return arr;
    }

归并排序

归并排序本质上就是分治!

但是跟快排的分治方法不一样

  • 以整个数组的中间点划分

  • 递归排序两边

  • 将两个有序的数组合并

    private static int[] mergeSort(int[] arr, int left, int right) {
    // 递归终止条件,如果左边界大于等于右边界则认为递归结束
    if (left >= right) {
    return arr;
    }
    // 设定一个分界值,这里是(left + right)/ 2
    int mid = left + right >> 1; // 位运算
    // 切割
    arr = mergeSort(arr, left, mid);
    arr = mergeSort(arr, mid + 1, right);
    // 归并,长度刚好是 left 到 right
    int[] temp = new int[right - left + 1];
    int i = left;
    int j = mid + 1;
    // 用来归并的索引
    int k = 0;
    while (i <= mid && j <= right) {
    // 如果是逆序则调整if条件
    if (arr[i] <= arr[j]) {
    temp[k++] = arr[i++];
    } else {
    temp[k++] = arr[j++];
    }
    }
    while (i <= mid) {
    temp[k++] = arr[i++];
    }
    while (j <= right) {
    temp[k++] = arr[j++];
    }
    // 根据归并后的数组重新赋值排序后的数组
    for (i = left, j = 0; i <= right; i++, j++) {
    arr[i] = temp[j];
    }
    return arr;
    }

二分

两种模板,分别是 LBS,和 RBS

复制代码
// 检查x是否满足某种性质  
private static boolean check(int x) {  
   /* ... */  
}  

// 区间[left, right]被划分成[left, mid]和[mid + 1, right]时使用: 
// 或者称之为左二分查询,查找左侧第一个满足条件的数
private static int leftBinarySearch(int[] arr, int left, int right) {  
   while (left < right) {  
      int mid = arr[left + right >> 1];  
      if (check(mid)) {  
         right = mid;    // check()判断mid是否满足性质  
      } else {  
         left = mid + 1;  
      }  
   }  
   return left;  
}  

// 区间[left, right]被划分成[left, mid - 1]和[mid, right]时使用:  
// 或者称之为右二分查询,查找右侧最后一个满足条件的数
private static int rightBinarySearch(int[] arr, int left, int right) {  
   while (left < right) {  
      int mid = arr[left + right + 1 >> 1];  
      if (check(mid)) {  
         left = mid;    // check()判断mid是否满足性质  
      } else {  
         right = mid - 1;  // 有加必有减
      }  
   }  
   return left;  
}
相关推荐
weixin_46430763几秒前
QT智能指针
java·数据库·qt
架构师沉默3 分钟前
程序员如何避免猝死?
java·后端·架构
佑白雪乐9 分钟前
<ACM进度212题>[2026-3-1,2026-3-26]
算法·leetcode
穿条秋裤到处跑12 分钟前
每日一道leetcode(2026.03.26):等和矩阵分割 II
算法·leetcode·矩阵
平凡灵感码头17 分钟前
C语言 printf 数据打印格式速查表
c语言·开发语言·算法
哔哔龙22 分钟前
Android OpenCV 实战:图片轮廓提取与重叠轮廓合并处理
android·算法
Zzxy24 分钟前
快速搭建SpringBoot项目并整合MyBatis-Plus
java·spring boot
hz_zhangrl25 分钟前
CCF-GESP 等级考试 2026年3月认证C++三级真题解析
c++·算法·程序设计·gesp·gesp2026年3月·gesp c++三级
星如雨グッ!(๑•̀ㅂ•́)و✧27 分钟前
WebFlux onErrorContinue 和 onErrorResume使用详解
java·人工智能
x_xbx29 分钟前
LeetCode:1. 两数之和
数据结构·算法·leetcode