16.讲二分查找(下):如何快速定位IP对应的省份地址

文章目录

  • 1. 二分查找的变形问题
  • 2. 变体一:查找第一个值等于给定值的元素
  • 3. 变体二:查找最后一个值等于给定值的元素
  • 4.变体三:查找第一个大于等于给定值的元素
  • 5.变体四:查找最后一个小于等于给定值的元素
  • 6.课后思考

问题:通过IP地址来查找IP归属地的功能。

1. 二分查找的变形问题

16.讲二分查找(下):如何快速定位IP对应的省份地址_第1张图片

2. 变体一:查找第一个值等于给定值的元素

16.讲二分查找(下):如何快速定位IP对应的省份地址_第2张图片
如何找到第一个8?

/**
   * 查找第一个值等于给定值的元素l
   *
   * @param arr
   * @param value
   * @return
   */
  public static int binarySearch1(int[] arr, int value) {
    int high = arr.length - 1;
    int low = 0;
    while (low <= high) {
      int mid = low + ((high - low) >> 1);
      if (arr[mid] > value) {
        high = mid - 1;
      } else if (arr[mid] < value) {
        low = mid + 1;
      } else {
        if (arr[mid - 1] != value || mid == 0) {
          return mid;
        } else {
          high = mid - 1;
        }
      }
    }
    return -1;
  }

3. 变体二:查找最后一个值等于给定值的元素

 /**
   * 查找最后一个值等于给定值的元素
   *
   * @param arr
   * @param value
   */
  public static int binarySearch2(int[] arr, int value) {
    int high = arr.length - 1;
    int low = 0;
    while (low <= high) {
      int mid = low + ((high - low) >> 1);
      if (arr[mid] > value) {
        high = mid - 1;
      } else if (arr[mid] < value) {
        low = mid + 1;
      } else {
        if (arr[mid + 1] != value || mid == arr.length - 1) {
          return mid;
        } else {
          low = mid + 1;
        }
      }
    }
    return -1;
  }

4.变体三:查找第一个大于等于给定值的元素

比如:数组中存储的这样一个序列:3,4,6,7,10。如果查找第一个大于等于5的元素,那就是6。


  /**
   * 查找第一个大于等于给定值的元素
   *
   * @param arr
   * @param value
   */
  public static int binarySearch3(int[] arr, int value) {
    int low = 0;
    int high = arr.length - 1;
    while (low <= high) {
      int mid = low + ((high - low) >> 1);
      if (arr[mid] >= value) {
        if (arr[mid - 1] < value || mid == 0) {
          return mid;
        } else {
          high = mid - 1;
        }
      } else {
        low = mid + 1;
      }
    }
    return -1;
  }

5.变体四:查找最后一个小于等于给定值的元素

/**
   * 查找最后一个小于等于给定值的元素
   *
   * @param arr
   * @param value
   */
  public static int binarySearch4(int[] arr, int value) {
    int low = 0;
    int high = arr.length - 1;
    while (low <= high) {
      int mid = low + ((high - low) >> 1);
      if (arr[mid] <= value) {
        if (arr[mid + 1] > value || mid == arr.length - 1) {
          return mid;
        } else {
          low = mid + 1;
        }
      } else {
        high = mid - 1;
      }
    }
    return -1;
  }

6.课后思考

我们今天讲的都是非常规的二分查找问题,今天的思考题也是一个非常规的二分查找问题。如果有序数组是一个循环有序数组,比如4,5,6,1,2,3。针对这种情况,如何实现一个求“值等于给定值”的二分查找算法呢?

你可能感兴趣的:(#,数据结构和算法,-,极客时间,王争,排序算法,算法,数据结构)