题目描述
统计一个数字在排序数组中出现的次数。
方法一:
扫描一遍数组,统计相应数字出现的次数。
时间复杂度为 O(n)
方法二:
时间复杂度为 O(logn)
数组是有序的,要想到使用二分查找的思路。
分别找到给定数字在数组中出现的第一个位置,和最后一个位置,相减+1,即得到个数。
找第一个位置和最后一个位置,在二分查找的基础上修改。
public class Solution {
public int GetNumberOfK(int[] array, int k) {
if (array == null || array.length == 0) {
return 0;
}
int firstPos = GetFirstK(array, k, 0, array.length - 1);
int lastPos = GetLastK(array, k, 0, array.length - 1);
if (firstPos > -1 && lastPos > -1) {
return lastPos - firstPos + 1;
} else {
return 0;
}
}
private int GetFirstK(int[] array, int k, int start, int end) {
while (start <= end) {
int middleIndex = (start + end) / 2;
if (array[middleIndex] == k) {
if (middleIndex > 0 && array[middleIndex - 1] != k || middleIndex == 0) {
return middleIndex;
} else {
end = middleIndex - 1;
}
} else if (array[middleIndex] > k) {
end = middleIndex - 1;
} else {
start = middleIndex + 1;
}
}
return -1;
}
private int GetLastK(int[] array, int k, int start, int end) {
while (start <= end) {
int middleIndex = (start + end) / 2;
if (array[middleIndex] == k) {
if (middleIndex < (array.length - 1) && array[middleIndex + 1] != k || middleIndex == array.length - 1) {
return middleIndex;
} else {
start = middleIndex + 1;
}
} else if (array[middleIndex] > k) {
end = middleIndex - 1;
} else {
start = middleIndex + 1;
}
}
return -1;
}
}
方法三:
如果 array数组中都是整数,可以稍微变一下,不是搜索k的两个位置,而是搜索 k-0.5 和 k+0.5 这两个数应该插入的位置,然后相减即可。
class Solution {
public int GetNumberOfK(int[] array, int k) {
if (array == null || array.length == 0) {
return 0;
}
return GetPosition(array, k + 0.5, 0, array.length - 1) - GetPosition(array, k - 0.5, 0, array.length - 1);
}
private int GetPosition(int[] array, double k, int start, int end) {
while (start <= end) {
int middleIndex = (start + end) / 2;
if (array[middleIndex] > k) {
end = middleIndex - 1;
} else {
start = middleIndex + 1;
}
}
return start;//start为最终要插的位置
}
}