统计一个数字在排序数组中出现的次数。例如输入{2,2,2,2,2,3,5,5}和数字2,输出5.
常规的顺序扫描法时间复杂度是O(n),可以进一步优化。用二分查找的方法进行查找可以把时间复杂度降为O(logn)。
代码如下:
1 int GetFirstK(int* data, int length, int k, int start, int end)//用二分查找法找到第一个K的位置 2 { 3 if (start > end) 4 { 5 return -1 ; 6 } 7 int MidIndex = (start + end) / 2 ; 8 int MidData = data[MidIndex]; 9 if (MidData == k) 10 { 11 if (MidIndex == 0 || MidIndex > 0 && data[MidIndex - 1] != k)//在首位或是不在首位且前一位不是K时 12 { 13 return MidIndex ; 14 } 15 else //不是第一个K时 16 { 17 end = MidIndex - 1 ; 18 } 19 } 20 else if ( MidData > k) 21 { 22 end = MidIndex - 1 ; 23 } 24 else 25 { 26 start = MidIndex + 1 ; 27 } 28 return GetFirstK(data, length, k, start, end) ; 29 } 30 31 int GetLastK(int* data, int length, int k, int start, int end)//用二分查找法找到最后一个K的位置 32 { 33 if (start > end) 34 { 35 return -1 ; 36 } 37 int MidIndex = (start + end) / 2 ; 38 int MidData = data[MidIndex]; 39 if (MidData == k) 40 { 41 if (MidIndex == length - 1 || MidIndex < length - 1 && data[MidIndex + 1] != k)//在末位或是不在末位且后一位不是K时 42 { 43 return MidIndex ; 44 } 45 else //不是最后一个K时 46 { 47 start = MidIndex + 1 ; 48 } 49 } 50 else if ( MidData > k) 51 { 52 end = MidIndex - 1 ; 53 } 54 else 55 { 56 start = MidIndex + 1 ; 57 58 } 59 60 return GetLastK(data, length, k, start, end) ; 61 62 } 63 int GetNumberOfK(int* data, int length, int k)//得到K的个数 64 { 65 if (!data || length < 1) 66 { 67 return 0 ; 68 } 69 int first = GetFirstK(data, length, k, 0, length - 1); 70 int last = GetLastK(data, length, k, 0, length - 1); 71 int number = 0 ; 72 if (first != -1 && last != -1) 73 { 74 number = last - first + 1 ; 75 } 76 return number ; 77 }