《劍指offer》:[38]數字在排序陣列中出現的次數

塵虛緣_KY發表於2016-06-19
    “溝通、學習能力就是看面試者能否清晰、有條理地表達自己,是否會在自己所得到的資訊不夠的情況下主動發問澄清,能否在得到一些暗示之後迅速做出反應糾正錯誤”                                                                                                                   ---陳黎明(MSoft-SDE)
題目:統計一個數字在排序陣列中出現的次數。例如輸入排序陣列{1,2,3,3,3,3,4,5}和數字3,由於3在陣列中出現的次數是4,所以輸出4。
方案一:順序掃描,找到一個計數器+1。這個不用多介紹,時間複雜為O(N),空間複雜度為O(1)。
方案二:此方案相比於方案一,效率稍有提高,但是其實也差不多。就是採用二分查詢,先找到給出的數字3,然後再向前以及向後順序查詢它的開頭和結尾。由於查詢該數字的時間複雜度為O(logN),但是順序查詢該數字的開始和結尾(如果對於N個數字,該數字出現了N次)的時間複雜度都為O(N),所以該演算法的時間複雜度仍然為O(N)。只有針對有N個元素,但是該元素出現的次數很少的情況下,此演算法相比於演算法二才有相對的提高。
方案三:次演算法是相比於方案2的提高改進。針對如果要統計的數字出現的次數和數字N的個數相同的情況下,其時間複雜度為O(N),如果我們在找到該數字後,在找其頭和尾的時候也採用二分查詢呢?那麼此時的情況就不一樣了!由於查詢該數字,以及查詢該數字的開始和結尾的時間複雜度都為O(logN),所以此時該演算法的時間複雜度為O(logN)。
方案三的具體實現程式碼如下:
#include <iostream>
using namespace std;
int arr[8]={1,2,3,3,3,3,4,5};
int GetFirstK(int *array,int k,int length,int start ,int end)
{
	if(start>end)
		return -1;
	int middleIndex=(start+end)/2;
	int middledata=array[middleIndex];
	if(middledata==k)
	{
		if(middleIndex>0 && array[middleIndex-1]!=k || middleIndex==0)
			return middleIndex;
		else
			end=middleIndex-1;
	}
	else if(middledata>k)
		end=middleIndex-1;
	else
		start=middleIndex+1;
	return GetFirstK(array,k,length,start,end);
}


int GetLastK(int *array,int k,int length,int start,int end)
{
	if(start>end)
		return -1;
	int middleIndex=(start+end)/2;
	int middledata=array[middleIndex];
	if(middledata==k)
	{
		if(middleIndex<length-1 && array[middleIndex+1]!=k || middleIndex==length-1)
			return middleIndex;
		else
			start=middleIndex+1;
	}
	else if(middledata>k)
		end=middleIndex-1;
	else
		start=middleIndex+1;
	return GetLastK(array,k,length,start,end);
}
int GetNumK(int *array,int length,int k)
{
	int number=0;
	if(array!=NULL && length>0)
	{
		int first=GetFirstK(array,k,length,0,length-1);
		int last=GetLastK(array,k,length,0,length-1);
		if(first>-1 && last>-1)
			number=last-first+1;
		else
			return 0;
	}
	return number;
}
int main()
{
	int num=GetNumK(arr,8,3);
	cout<<"3出現的次數是:"<<num<<endl;
	system("pause");
	return 0;
}

執行結果是:



相關文章