面试题整理11 数字在排序数组中出现的次数
《劍指offer》面試題38:
題目:統(tǒng)計(jì)一個(gè)數(shù)字在排序數(shù)組中出現(xiàn)的次數(shù)。例如輸入排序數(shù)組{1,2,3,3,3,3,4,5}和數(shù)字3,由于3在此數(shù)組中出現(xiàn)了4次,因此輸出4。
分析:看到排序數(shù)組想到二分法解決問(wèn)題,假設(shè)輸入數(shù)字為k,當(dāng)中間數(shù)大于k時(shí),在前部分查找;當(dāng)中間數(shù)小于k時(shí)在后部分查找;當(dāng)中間數(shù)等于k時(shí),前部分和后部分都有可能。
???????? 此題之所以記錄是因?yàn)殛P(guān)鍵在于中間數(shù)等于k時(shí)的處理方法的不同和效率的差異比較。
(1)自己寫的代碼,當(dāng)中間數(shù)等于k時(shí),遞歸調(diào)用前部分、后部分,前面部分k出現(xiàn)的次數(shù)+后面部分k出現(xiàn)的次數(shù)+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第一次和最后一次出現(xiàn)的位置,兩者相減+1為總次數(shù)。
??????? 此種方法相比于自己寫的代碼的優(yōu)勢(shì)在于,當(dāng)k出現(xiàn)次數(shù)多時(shí),遞歸次數(shù)少,極限整個(gè)數(shù)組都是k時(shí),比(1)效率高很多;當(dāng)然k沒(méi)有出現(xiàn)或者出現(xiàn)一兩次時(shí)遞歸次數(shù)相仿。在求第一次出現(xiàn)時(shí),當(dāng)中間數(shù)等于k時(shí),只遞歸前面部分;求最后一次時(shí),當(dāng)中間數(shù)等于k時(shí),只求后面部分。
應(yīng)采用此種方法。但是示例代碼中有一點(diǎn)不好,先求第一次出現(xiàn),接著求最后一次出現(xiàn),然后再進(jìn)行判斷,這樣當(dāng)?shù)谝淮畏祷?1時(shí)還需要再求第二遍,下面將判斷順序改了。
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; }// 找到數(shù)組中第一個(gè)k的下標(biāo)。如果數(shù)組中不存在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); }// 找到數(shù)組中最后一個(gè)k的下標(biāo)。如果數(shù)組中不存在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); }總結(jié)
以上是生活随笔為你收集整理的面试题整理11 数字在排序数组中出现的次数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 面试题整理10 最小的k个数
- 下一篇: 面试题整理12 求字符串括号最大深度子串