题目描述:
统计一个数字在排序数组中出现的次数。
这个问题的初始解法就是,在排序的数组中利用折半查找,这个k之后,然后以这个为中心,分别向左右遍历,统计k出现的次数。
这种方法虽然利用了折半查抄,使得定位这个元素的时间复杂度为O(logn),但是在以这个元素为中心左右查找的时候,时间复杂度又降低为了O(n),所以总体的时间复杂度还是O(n)。
新的想法:分别利用两次折半查找,找到k的第一次出现的位置,然后再找到k最后一次出现的位置。这样就能直接的求出k的个数,而不用任何的遍历过程。
int GetNumberOfK(vector data ,int k) { int first = 0; int last = data.size() - 1; int firstKIndex = GetFirstK(data, 0, last, k); if(firstKIndex == -1) return 0; int lastKIndex = GetLastK(data, 0, last, k); return lastKIndex - firstKIndex + 1;}int GetFirstK(vector &arr, int first, int last, int k){ while(first <= last) { int mid = (first + last) / 2; if(arr[mid] > k) { last = mid - 1; } else if(arr[mid] < k) { first = mid + 1; } else { if(mid == 0 || arr[mid - 1] != k) { return mid; } else { last = mid - 1; } }//else }//while return -1;}int GetLastK(vector &arr, int first, int last, int k){ while(first <= last) { int mid = (first + last) / 2; if(arr[mid] > k) { last = mid - 1; } else if(arr[mid] < k) { first = mid + 1; } else { if(mid == last || arr[mid + 1] != k) { return mid; } else { first = mid + 1; } }//else }//while return -1;}
在没有查找到k的时候,注意要返回一个标志-1,表示查找未成功。