zoukankan      html  css  js  c++  java
  • 二分法查找Binary Search

    1. 二分法查找算法,判断一个数是否在一个有序数组中存在,最快的方法就是二分法,时间复杂度为O(Logn)

    2. 利用二分思想,每次与中间数值比较,缩小查找范围。

    3. 写好二分查找需要注意,循环条件是low <= high; mid取值最好不用mid=(low+high)/2, 而是用low + ((high-low) >>1),位运算效率高,且避免溢出。

    应用:

    a. 查找第一个(最后一个)值等于给定值的元素,数组可能存在重复的元素。对于我们做工程的人来说,代码易懂,bug free,其实最重要。

    public int bsearch(int[] a, int n, int value) {
      int low = 0;
      int high = n - 1;
      while (low <= high) {
        int mid =  low + ((high - low) >> 1);
        if (a[mid] > value) {
          high = mid - 1;
        } else if (a[mid] < value) {
          low = mid + 1;
        } else {
          if ((mid == 0) || (a[mid - 1] != value)) return mid; // 第一个
        // if ((mid == n - 1) || (a[mid + 1] != value)) return mid; //最后一个
    else high = mid - 1; } } return -1; }

    b. 查找第一个大于等于给定值的元素 / 查找最后一个小于等于给定值的元素

    public int bsearch(int[] a, int n, int value) {
      int low = 0;
      int high = n - 1;
      while (low <= high) {
        int mid =  low + ((high - low) >> 1);
        if (a[mid] >= value) {
          if ((mid == 0) || (a[mid - 1] < value)) return mid;
          else high = mid - 1;
        } else {
          low = mid + 1;
        }
      }
      return -1;
    }
    
    public int bsearch(int[] a, int n, int value) {
      int low = 0;
      int high = n - 1;
      while (low <= high) {
        int mid =  low + ((high - low) >> 1);
        if (a[mid] > value) {
          high = mid - 1;
        } else {
          if ((mid == n - 1) || (a[mid + 1] > value)) return mid;
          else low = mid + 1;
        }
      }
      return -1;
    }

    c.根据一个IP地址查询归属地,ip地址是可以转换为一个数值的, 把原来的区间起始地址构造成一个有序数组,然后对应查找最后一个最后一个小于等于给定值的元素,找到后在到对应区间去看是否在区间内,在则显示,不在就显示未找到。

    d.求平方根

    class Solution {
        public int mySqrt(int x) {
            int l = 0, r = x, ans = -1;
            while (l <= r) {
                int mid = l + (r - l) / 2;
                if ((long)mid * mid <= x) {
                    ans = mid;
                    l = mid + 1;
                }
                else {
                    r = mid - 1;
                }
            }
            return ans;
        }
    }

    e.二分查找的优势在于近似查找,存在重复元素,这是散列表和二叉查找树没法实现的。

  • 相关阅读:
    Android SDK
    1055
    清除浮动的三种方式
    解决块状元素垂直外边距的塌陷问题
    drf 验证接口权限
    Linux常用指令
    Linux安装python3,virtualenv和virtualenvwrapper
    Linux基本命令2
    Linux之文档与目录结构
    Linux基本命令
  • 原文地址:https://www.cnblogs.com/roy1/p/13544991.html
Copyright © 2011-2022 走看看