剑指Offer 53-I. 在排序数组中查找数字I

方法一:二分法

排序数组 nums 中的所有数字 target 形成一个窗口,记窗口的 左 / 右边界 索引分别为 left 和 right ,分别对应窗口左边 / 右边的首个元素。

本题要求统计数字 target 的出现次数,可转化为:使用二分法分别找到 左边界 left 和 右边界 right ,易得数字 targettarget 的数量为 right - left - 1 。

对于左边界,实际上是要找第一个大于等于target的数;对于右边界则是要找第一个大于target的数。

左边界,因为是左,所以当找到target时并不会停下来,而是让right继续等于mid - 1.

 1 /**
 2  * @param {number[]} nums
 3  * @param {number} target
 4  * @return {number}
 5  */
 6 var search = function(nums, target) {
 7     let ans = 0;
 8     const leftIndex = binarySearch(nums, target, true);
 9     const rightIndex = binarySearch(nums, target, false) - 1;
10     if(leftIndex <= rightIndex && rightIndex < nums.length && nums[leftIndex] == target && nums[rightIndex] == target) {
11         ans = rightIndex - leftIndex + 1;
12     }
13     return ans;
14 };
15 
16 /**
17  * @param {number[]} nums
18  * @param {number} target
19  * @param {boolean} lower
20  * @return {number}
21  */
22  var binarySearch = function(nums, target, lower) {
23      let left = 0, right = nums.length - 1, ans = nums.length;//可能是针对数组长度为1时的情况
24      while(left <= right) {
25          const mid = Math.floor((left + right) / 2);
26          if(nums[mid] > target || (lower && nums[mid] >= target)) {
27              right = mid - 1;
28              ans = mid;
29          }else {
30              left = mid + 1;
31          }
32      }
33      return ans;
34  }

或者

 1 class Solution {
 2     public int search(int[] nums, int target) {
 3         // 搜索右边界 right
 4         int i = 0, j = nums.length - 1;
 5         while(i <= j) {
 6             int m = (i + j) / 2;
 7             if(nums[m] <= target) i = m + 1;
 8             else j = m - 1;
 9         }
10         int right = i;
11         // 若数组中无 target ,则提前返回
12         if(j >= 0 && nums[j] != target) return 0;
13         // 搜索左边界 right
14         i = 0; j = nums.length - 1;
15         while(i <= j) {
16             int m = (i + j) / 2;
17             if(nums[m] < target) i = m + 1;
18             else j = m - 1;
19         }
20         int left = j;
21         return right - left - 1;
22     }
23 }

 

posted @ 2021-09-05 15:33  雪之下。  阅读(46)  评论(0)    收藏  举报