面试题整理11 数字在排序数组中出现的次数
生活随笔
收集整理的這篇文章主要介紹了
面试题整理11 数字在排序数组中出现的次数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
《劍指offer》面試題38:
題目:統計一個數字在排序數組中出現的次數。例如輸入排序數組{1,2,3,3,3,3,4,5}和數字3,由于3在此數組中出現了4次,因此輸出4。
分析:看到排序數組想到二分法解決問題,假設輸入數字為k,當中間數大于k時,在前部分查找;當中間數小于k時在后部分查找;當中間數等于k時,前部分和后部分都有可能。
???????? 此題之所以記錄是因為關鍵在于中間數等于k時的處理方法的不同和效率的差異比較。
(1)自己寫的代碼,當中間數等于k時,遞歸調用前部分、后部分,前面部分k出現的次數+后面部分k出現的次數+1。
int GetNumberOfK1(int* data, int length, int k) {if( data == NULL || length <= 0 )return 0;return FindKTimes(data,0,length-1,k); } int FindKTimes( int *data, int start, int end,int k) {if( start > end || data[start] > k || data[end] < k ){return 0;}if( start == end ){if( data[start] == k ){return 1;}else{return 0;}}int middle = (start + end)/2;if(data[middle] > k){return FindKTimes(data,start,middle-1,k);}else if( data[middle] < k ){return FindKTimes(data,middle+1,end,k);}else{return FindKTimes(data,start,middle-1,k)+ FindKTimes(data,middle+1,end,k)+1;} }(2)《劍指offer》中代碼,采取二分法分別求k第一次和最后一次出現的位置,兩者相減+1為總次數。
??????? 此種方法相比于自己寫的代碼的優勢在于,當k出現次數多時,遞歸次數少,極限整個數組都是k時,比(1)效率高很多;當然k沒有出現或者出現一兩次時遞歸次數相仿。在求第一次出現時,當中間數等于k時,只遞歸前面部分;求最后一次時,當中間數等于k時,只求后面部分。
應采用此種方法。但是示例代碼中有一點不好,先求第一次出現,接著求最后一次出現,然后再進行判斷,這樣當第一次返回-1時還需要再求第二遍,下面將判斷順序改了。
int GetNumberOfK(int* data, int length, int k) {int number = 0;/*if(data != NULL && length > 0){int first = GetFirstK(data, length, k, 0, length - 1);int last = GetLastK(data, length, k, 0, length - 1);if(first > -1 && last > -1)number = last - first + 1;}*/if(data != NULL && length > 0){int first = GetFirstK(data, length, k, 0, length - 1);if( first > -1){int last = GetLastK(data, length, k, 0, length - 1);if(last > -1)number = last - first + 1;}}return number; }// 找到數組中第一個k的下標。如果數組中不存在k,返回-1 int GetFirstK(int* data, int length, int k, int start, int end) {if(start > end )return -1;int middleIndex = (start + end) / 2;int middleData = data[middleIndex];if(middleData == k){if((middleIndex > 0 && data[middleIndex - 1] != k) || middleIndex == 0)return middleIndex;elseif( middleIndex == start)return middleIndex;end = middleIndex - 1;}else if(middleData > k)end = middleIndex - 1;elsestart = middleIndex + 1;return GetFirstK(data, length, k, start, end); }// 找到數組中最后一個k的下標。如果數組中不存在k,返回-1 int GetLastK(int* data, int length, int k, int start, int end) {if(start > end)return -1;int middleIndex = (start + end) / 2;int middleData = data[middleIndex];if(middleData == k){if((middleIndex < length - 1 && data[middleIndex + 1] != k) || middleIndex == length - 1)return middleIndex;elsestart = middleIndex + 1;}else if(middleData < k)start = middleIndex + 1;elseend = middleIndex - 1;return GetLastK(data, length, k, start, end); }總結
以上是生活随笔為你收集整理的面试题整理11 数字在排序数组中出现的次数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面试题整理10 最小的k个数
- 下一篇: ntfs 格式在linux下挂载