题目
统计一个数字在升序数组中出现的次数。
思路
题目已经明确这个就是一个有序并且还是一个升序的数组。那么我们就可以安心的使用二分进行查找到该数。
步骤:
- 设置两个变量依次是first这个数第一次出现的位置,last这个数已经不再出现的位置
- 每一次求出mid。对k进行比较。
- 如果
a[mid] == k
,由于是升序的数组,那么我们就开始从mid出发,往前面检索,查找到最后出现k的地方,也就是k第一次出现的地方 - 如果
a[mid] != k
- 如果
a[mid] > k
我们修改right = mid
- 如果
a[mid] < k
我们修改left = mid + 1
( 注意:如果找不到该数,left 会变成 a.length )
- 如果
- 如果
- 最后
last - first
就是该数出现的次数。注意判断一下,last和first不会存在的情况。这里使用了二分的特性。如果找不到 last 会变成 a.length,因此只要只需要判断fist存在即可。
AC代码
public class Solution {
public static int GetNumberOfK(int[] array, int k) {
if(array.length == 0)
return 0;
int first = f(array,k); // 找k
int last = f(array,k+1); // 找k+1
//System.out.println(last - first);
if(first == array.length || array[first] != k)
return 0;
else
return last - first;
}
public static int f(int[] a, int k) {
int left = 0;
int right = a.length;
int mid = (right + left) / 2;
if(a[mid] == k) {
int i ;
for(i = mid - 1 ; i >= left;i--) {
if(a[i] != k)
break;
}
return i + 1;
}
while(left < right) {
// 开始查找
// 他是一个升序数组
// 算到中间进行比较
if(a[mid] >= k) {
right = mid;
}else if(a[mid] < k) {
left = mid + 1;
}
if(a[mid] == k) {
int i ;
for(i = mid - 1 ; i >= left;i--) {
if(a[i] != k)
break;
}
return i + 1;
}
mid = (right + left) / 2;
}
// 说明未找到。那就是最末尾 + 1
return left;
}
}