题目描述
统计一个数字在升序数组中出现的次数。
我的题目分析
我设了两个指针,遍历数组,查找是否有与指定数字相等的元素;
如果存在,则小指针记录下第一个等于k的索引值;
大指针继续向下移动,寻找小指针之后第一个与k不相等的元素索引,记录下索引值,如果一相等的话,则大指针为数组的长度值;
返回的是大指针减去小指针的值;
我的代码
/**
* 统计一个数字在升序数组中出现的次数。
*/
public class Solution {
public int GetNumberOfK(int [] array , int k) {
if (array == null) return 0;
int firstPoint = 0;//指针从左往右移动,初始指向最左边
int lastPoint = 0;
//从左往右找,找到第一个目标值,并记录其数组下标
for (int i = 0; i < array.length; i++) {
if (array[i]==k){
firstPoint = i;
break;
}
}
//从找到的第一个目标开始,继续往右找
for (int j = firstPoint; j < array.length ; j++) {
if (array[j] != k){//若不相等,则说明不需要再找了,直接break
lastPoint = j;
break;
}
else {//若相等,则说明还需要继续找,需要在已经找到的第一个目标值与数组剩下的值中继续比较
lastPoint = array.length;
}
}
return lastPoint-firstPoint;
}
}
改进题目分析
我用的类似双指针的方法,看起来挺不错的,但是实际上效率不高,和直接遍历一遍效率差不多,看网上大佬用二分加双指针(毕竟看到有序就用二分)
- 首先用二分法,找到第一个k
- 找到第一个k之后,用双指针i,j向两边扩展,i,j初始指向找到的第一个k,i往左找,j往右找,(因为有序,所以时间复杂度为O(n),与二分O(nlogn)相加还是O(nlogn))
改进代码
public class Solution {
public int GetNumberOfK(int [] array , int k) {
if(array==null||array.length == 0)return 0;
int position = BinarySearch(array,k);
int i,j;
i = j = position;
if (position!=-1){
while (i>=0&&array[i]==k)i--;
while (j<array.length&&array[j]==k)j++;
return j-i-1;
}
else {
return 0;
}
}
public int BinarySearch(int[] array, int key){
int start = 0;
int end = array.length-1;
int mid = 0;
while (start<=end){
mid = (start + end)>>1;
if (array[mid]<key){
start = mid + 1;
}
else if (array[mid]>key){
end = mid - 1;
}
else {
return mid;
}
}
return -1;
}
}