数字在排序数组中出现的次数
描述
统计一个数字在排序数组中出现的次数。
代码 (Java)
public class Solution {
public int GetNumberOfK(int [] array , int k) {
int number = 0;
if (array != null && array.length > 0) {
int firstIndex = GetFirstK(array, k, 0, array.length - 1);
int lastIndex = GetLastK(array, k, 0, array.length - 1);
if (firstIndex > -1 && lastIndex > -1)
number = lastIndex - firstIndex + 1;
}
return number;
}
public int GetFirstK(int[] array, int k, int start, int end) {
if (start > end)
return -1;
int mid = (start + end) / 2;
if (array[mid] == k) {
if ((mid > 0 && array[mid - 1] != k) || mid == 0)
return mid;
else
end = mid - 1;
} else if (array[mid] > k) {
end = mid - 1;
} else {
start = mid + 1;
}
return GetFirstK(array, k, start, end);
}
public int GetLastK(int[] array, int k, int start, int end) {
if (start > end)
return -1;
int mid = (start + end) / 2;
if (array[mid] == k) {
if ((mid < array.length - 1 && array[mid + 1] != k) || mid == array.length - 1)
return mid;
else
start = mid + 1;
} else if (array[mid] > k) {
end = mid - 1;
} else {
start = mid + 1;
}
return GetLastK(array, k, start, end);
}
}
思路
- 本题的思路是灵活使用二分查找,像这里可以用两次二分法,分别查找第一个和最后一个 k 的下标,时间复杂度是O(logn)。如果用一次二分查找到 k 后,再向两边扩散遍历的话,其复杂度仍然是O(n);
- 找第一个k和最后一个k的区别,是要根据找到的中间k的前一个数和后一个数是否仍然是k,然后进行相应的递归。