简述Java有序数组中某个数字的出现次数 ?
参考答案:
在Java中,对于有序数组中某个数字的出现次数,我们可以采用两种不同的方法来进行统计,这两种方法的时间复杂度分别是O(N)和O(logN)。
- O(N)时间复杂度的方法: 这种方法通过直接遍历数组并比较每个元素与指定的数字是否相等来实现。具体实现时,我们可以使用一个计数器变量来记录出现的次数,然后遍历数组,每当发现一个与指定数字相等的元素时,就增加计数器的值。最后返回计数器的值即可。
public static int countNumber(int[] array, int number) {
if (array == null || array.length <= 0) {
return 0;
}
int count = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == number) {
count++;
}
}
return count;
}
这种方法简单易懂,但是时间复杂度较高,为O(N),其中N为数组的长度。
- O(logN)时间复杂度的方法: 这种方法利用了二分查找的思想,首先找到数组中第一个出现指定数字的位置,然后从该位置起分别向左和向右查找,直到找到不再出现该数字的位置为止。具体实现时,我们可以使用二分查找算法来找到第一个出现指定数字的位置,然后向左和向右查找时,可以采用双指针法来进行。
public static int countNumber(int[] array, int number) {
if (array == null || array.length <= 0) {
return 0;
}
int left = findFirstPosition(array, number);
if (left == -1) {
return 0;
}
int right = findLastPosition(array, number, left);
return right - left + 1;
}
private static int findFirstPosition(int[] array, int number) {
int left = 0;
int right = array.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (array[mid] == number) {
if (mid == 0 || array[mid - 1] != number) {
return mid;
} else {
right = mid - 1;
}
} else if (array[mid] < number) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
private static int findLastPosition(int[] array, int number, int start) {
int left = start;
int right = array.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (array[mid] == number) {
if (mid == array.length - 1 || array[mid + 1] != number) {
return mid;
} else {
left = mid + 1;
}
} else if (array[mid] < number) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
这种方法的时间复杂度为O(logN),其中N为数组的长度,但是实现起来相对复杂一些。
需要注意的是,这种方法的前提是数组必须是有序的,如果数组无序,那么这种方法就无法使用。另外,由于二分查找算法的特性,当数组中不存在指定的数字时,返回的结果可能是错误的,因此在使用时需要特别注意。