• 二分查找


    【二分查找】

    二分查找是一个基础的算法,也是面试中常考的一个知识点。二分查找就是将查找的键和子数组的中间键作比较,如果被查找的键小于中间键,就在左子数组继续查找;如果大于中间键,就在右子数组中查找,否则中间键就是要找的元素。

    常规的二分查找:

     1 int binarySearch(int a[],int n,int key)
     2 {
     3     int left = 0;
     4     int right = n-1;
     5     while (left <= right )  //不要忘记等号
     6     {
     7         int mid = (left + right) / 2;
     8         if (a[mid] > key)
     9             right = mid - 1;
    10         else if (a[mid] < key)
    11             left = mid + 1;
    12         else
    13             return mid;
    14     }
    15     return -1;
    16 }

    这里强调下不要忘记 left <= right 的等号   比如a[3] = {1,3,5} 我们需要查找5  如果 letf < right 的话就不会进入while循环,这会导致找不到结果

    【变形一】 查找第一个与key相等的元素

    因为找第一个 所以不断往左边找 所以等于号加在 right = mid-1

     1 int binarySearch(int a[],int n,int key)
     2 {
     3     int left = 0;
     4     int right = n-1;
     5     while (left <= right )
     6     {
     7         int mid = (left + right) / 2;
     8         if (a[mid] >= key)
     9             right = mid - 1;
    10         else if (a[mid] < key)
    11             left = mid + 1;
    12         }
    13     if (left < n && a[left] == key)
    14         return left;
    15 }

    【变形二】查找最后一个与key相等的元素

    因为找最后一个 所以等号加在left = mid + 1

     1 int binarySearch(int a[],int n,int key)
     2 {
     3     int left = 0;
     4     int right = n-1;
     5     while (left <= right )
     6     {
     7         int mid = (left + right) / 2;
     8         if (a[mid] > key)
     9             right = mid - 1;
    10         else if (a[mid] <= key)
    11             left = mid + 1;
    12         }
    13     if (right < n && a[right] == key)
    14         return right;
    15 }

    【变形三】查找最后一个小于或等于key的元素

    小于等于类似 等于  所以同样加载left = mid + 1

     1 int binarySearch(int a[],int n,int key)
     2 {
     3     int left = 0;
     4     int right = n-1;
     5     while (left <= right )
     6     {
     7         int mid = (left + right) / 2;
     8         if (a[mid] > key)
     9             right = mid - 1;
    10         else if (a[mid] <= key)
    11             left = mid + 1;
    12         }
    13     return right;
    14 }

    【变形四】查找最后一个小于key的元素

    小于的话要不断的往左边找 所以等号加在right = mid - 1

     1 int binarySearch(int a[],int n,int key)
     2 {
     3     int left = 0;
     4     int right = n-1;
     5     while (left <= right )
     6     {
     7         int mid = (left + right) / 2;
     8         if (a[mid] >= key)
     9             right = mid - 1;
    10         else if (a[mid] < key)
    11             left = mid + 1;
    12     }
    13     return right;
    14 }

    【变形五】查找第一个等于或大于key的元素

    等于或大于类似 等于   等号加在right = mid - 1

     1 int binarySearch(int a[],int n,int key)
     2 {
     3     int left = 0;
     4     int right = n-1;
     5     while (left <= right )
     6     {
     7         int mid = (left + right) / 2;
     8         if (a[mid] >= key)
     9             right = mid - 1;
    10         else if (a[mid] < key)
    11             left = mid + 1;
    12     }
    13     return left;
    14 }

    【变形六】查找第一个大于key的元素

    大于要不断往右边找 等号加在left = mid + 1

     1 int binarySearch(int a[],int n,int key)
     2 {
     3     int left = 0;
     4     int right = n-1;
     5     while (left <= right )
     6     {
     7         int mid = (left + right) / 2;
     8         if (a[mid] > key)
     9             right = mid - 1;
    10         else if (a[mid] <= key)
    11             left = mid + 1;
    12     }
    13     return left;
    14 }

    变形总结:

    如果是找到第一个则都是返回left   如果是最后一个则返回right

    如果我们要找第一个 > key 的元素或者元素的下标   可以利用    upper_bound  返回第一个大于的元素的下标; 

                                    int pos = upper_bound(a,a+n,key) - a;   (默认数组a从0开始记录)

    如果我们要找第一个 >= key 的元素或者元素的下标  可以利用       lower_bound返回第一个大于等于元素的下标;

                                   int pos = lower_bound(a,a+n,key) - a;    (默认数组a从0开始记录)

  • 相关阅读:
    Gnome-keyring总是提示输入密码问题
    ubuntu下制作u盘启动盘
    ubuntu下制作u盘启动盘
    comgt拨号
    linux命令学习笔记
    U-Boot启动过程完全分析
    从Linux程序中执行shell(程序、脚本)并获得输出结果
    Git fetch和git pull的区别
    php如何获取远程文件内容的函数
    php验证邮箱和ip地址方法总汇
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11166481.html
Copyright © 2020-2023  润新知