数据结构——二分搜索
递归实现
时间、空间复杂度均为 O(logN)
/** * 二分搜索(递归实现) * @param A 待搜索数组 * @param num 搜索值 * @param left 区间左指针 * @param right 区间右指针 * @param mid 基准 */ private static void search(int[] A, int num, int left, int right, int mid) { if (A[mid] == num) { // 如果找到要找的数,记录其下标 res = mid; } if (left >= right) return ; if (A[mid] >= num) { // 出现在左边 right = mid - 1; mid = left + (right-left)/2; search(A, num, left, right, mid); } if (A[mid] < num) { // 出现在右边 left = mid + 1; mid = left + (right-left)/2; search(A, num, left, right, mid); } }
非递归实现
时间复杂度为 O(logN),空间复杂度为 O(1)
/** * 二分搜索(非递归实现) * @param A 带搜索数组 * @param n 数组长度 * @param num 搜索值 * @return */ private static int search2(int[] A, int n, int num) { int left = 0; int right = n - 1; int res = -1; while (left <= right) { int mid = left + (right - left)/2; if (A[mid] == num) { res = mid; right = mid - 1; } if (A[mid] >= num) { // 左区间 right = mid - 1; } else { left = mid + 1; } } return res; } private static int search3(int[] arr, int n, int num) { int left = 0; int right = n-1; while (left <= right) { int mid = left + ((right-left)>>1); if (arr[mid] > num) { right = mid-1; }else if (arr[mid] < num) { left = mid+1; }else { return mid; } } return -1; }
简单应用:在有序数组中查找某数 num 的出现次数 m
给定数组 arr 和要找的数为 num。
首先确定 num 最左出现的下标位置,记为 indexL,再确定 num 在数组中最右出现的下标位置,记为 indexR。
比如 arr = {0,1,1,2,3,3,3,4}
当 num = 1 时,indexL = 1,indexR = 2,出现次数 m = indexR - indexL + 1;
当 num = 2 时,indexL = 3,indexR = 3,m = 1,因为 indexL == indexR;
当 num = 4 时,indexL = 7,indexR = 7;m = 1;
/** * Created by zhengbinMac on 2017/4/11. */ public class Search { public static void main(String[] args) { int[] arr = {0, 1, 1, 2, 3, 3, 3, 4}; int m = search(arr, 3); System.out.println(m); } private static int search(int[] arr, int num) { int indexL = 0; int indexR = 0; int left = 0; int right = arr.length - 1; // 找到数组中为 num 的最左下标位置 while (left <= right) { int mid = left + ((right - left) >> 1); if (arr[mid] > num) { right = mid - 1; }else if (arr[mid] < num) { left = mid + 1; }else { right = mid - 1; indexL = mid; } } left = 0; right = arr.length - 1; // 找到数组中为 num 的最右下标位置 while (left <= right) { int mid = left + ((right - left) >> 1); if (arr[mid] > num) { right = mid - 1; }else if (arr[mid] < num) { left = mid + 1; }else { left = mid + 1; indexR = mid; } } if (indexR == indexL) { return 1; }else { return indexR - indexL + 1; } } }
梦想要一步步来!