题目描述:
统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums 是一个非递减数组
-109 <= target <= 109
思路:
首先想到的就是用indexOf()方法和lastIndexOf()方法查找第一个target和最后一个target,不过复杂度上不够优化,没有充分利用数组非递减的特性
然后看题解知道可以用二分找第一个target和第一个大于target的值的位置(我的二分处理实在不行,尤其是在跳出循环条件和快要找到的细节处理上)
1. indexOf() + lastIndexOf():
1 /*JavaScript*/ 2 /** 3 * @param {number[]} nums 4 * @param {number} target 5 * @return {number} 6 */ 7 var search = function(nums, target) { 8 const begin = nums.indexOf(target) 9 if(begin === -1) return 0 10 return nums.lastIndexOf(target) - begin + 1 11 };
2. 二分:
1 /*JavaScript*/ 2 /** 3 * @param {number[]} nums 4 * @param {number} target 5 * @return {number} 6 */ 7 var search = function(nums, target) { 8 const len = nums.length 9 if(!len) return 0 10 //传入左右边界和目标值 11 function binary_search(l, r, target) { 12 while(l<r) { 13 const mid = l+r>>1 14 if(nums[mid] < target) l = mid+1 15 else if(nums[mid] > target) r = mid-1 16 else r = mid 17 } 18 // 若nums[r] === target 说明找到第一个目标值,下面这个对r是否要加一的处理,主要是针对r越界和找第一个大于target的值的位置 19 return r+(r<0 || r<len && nums[r]<target ? 1 : 0) 20 } 21 const left = binary_search(0, len-1, target) //找第一个target 22 if(nums[left] !== target) return 0 23 const right = binary_search(left+1, len-1, target+1) //找第一个大于target的值的位置 24 return right-left 25 };