统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
限制:
0 <= 数组长度 <= 50000
这道题看似非常简单,但是在面试中经常出现。
这种简单的题目,面试官往往考察的不是是否能解答出来,而是对时间复杂度和空间复杂度有着更高的要求。
- 解法一
很容易想到的解法,遍历数组,统计出现次数。
class Solution {
public int search(int[] nums, int target) {
int count = 0;
for(int i = 0;i < nums.length;i++){
if(nums[i] == target){
count++;
}
}
return count;
}
}
- 解法二
HashMap统计出现次数
class Solution {
public int search(int[] nums, int target) {
HashMap<Integer,Integer> map = new HashMap<>();
for(int i = 0;i < nums.length;i++){
map.put(nums[i],map.getOrDefault(nums[i],0)+1);
}
if(map.get(target) == null){
return 0;
}else{
return map.get(target);
}
}
- 解法三
面试官满意的解法
- 时间复杂度 O(log N) : 二分法为对数级别复杂度。
- 空间复杂度 O(1) : 几个变量使用常数大小的额外空间。
class Solution {
public int search(int[] nums, int target) {
int i= 0, j= nums.length -1;
//找出右边界i
while(i <= j){
int m = (i + j)/2;
if(nums[m]<= target) i = m+1;
else if(nums[m]> target) j = m-1;
}
//此时
int right = i;
// 若数组中无 target ,则提前返回
if(j >= 0 && nums[j] != target) return 0;
//找出左边界j
i= 0; j= nums.length -1;
while(i <= j ){
int m = (i + j)/2;
if(nums[m]< target) i = m+1;
else if(nums[m]>= target) j = m-1;
}
int left = j;
return right - left -1;
}
}