《劍指offer》:[38]數字在排序陣列中出現的次數
“溝通、學習能力就是看面試者能否清晰、有條理地表達自己,是否會在自己所得到的資訊不夠的情況下主動發問澄清,能否在得到一些暗示之後迅速做出反應糾正錯誤” ---陳黎明(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)。
方案三的具體實現程式碼如下:
題目:統計一個數字在排序陣列中出現的次數。例如輸入排序陣列{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;
}
執行結果是:
相關文章
- 【劍指offer】數字在排序陣列中出現的次數排序陣列
- 劍指Offer-39-數字在排序陣列中出現的次數排序陣列
- 劍指OFFER-數字在升序陣列中出現的次數(Java)陣列Java
- [劍指offer題解][Java]陣列中出現次數超過一半的數字Java陣列
- 力扣 - 劍指 Offer 39. 陣列中出現次數超過一半的數字力扣陣列
- 九度 1349 數字在排序陣列中出現的次數排序陣列
- 劍指 Offer 56 - I. 陣列中數字出現的次數陣列
- Leetcode 劍指 Offer 39. 陣列中出現次數超過一半的數字LeetCode陣列
- JZ-037-數字在排序陣列中出現的次數排序陣列
- 劍指offer 陣列中只出現一次的數字陣列
- 《劍指offer》:[40]陣列中只出現一次的數字陣列
- 【劍指offer】陣列中只出現一次的數字(1)陣列
- 【劍指offer】陣列中只出現一次的數字(2)陣列
- 劍指offer:旋轉陣列的最小數字陣列
- 劍指offer 旋轉陣列的最小數字陣列
- 劍指Offer--陣列中重複的數字陣列
- 劍指offer-轉陣列的最小數字-php陣列PHP
- 《劍指offer》:[51]陣列中的重複數字陣列
- 每日一題 - 劍指 Offer 53 - I. 在排序陣列中查詢數字 I每日一題排序陣列
- 【劍指offer】7.旋轉陣列的最小數字陣列
- 劍指 Offer 11. 旋轉陣列的最小數字陣列
- 【劍指 Offer】11. 旋轉陣列的最小數字陣列
- 【劍指offer】把陣列排成最小的數陣列
- 找到陣列中出現特定次數數字的問題陣列
- 陣列中出現兩次的數陣列
- 陣列中出現次數超過一半的數字陣列
- 劍指offer之列印超過陣列一半的數字陣列
- 48 陣列中出現次數超過一半的數字陣列
- 求出陣列中出現次數大於一半的數字陣列
- 劍指Offer-34-把陣列排成最小的數陣列
- 劍指offer——把陣列排成最小的數C++陣列C++
- Leetcode 劍指 Offer 03. 陣列中重複的數字LeetCode陣列
- 劍指offer刷題之路--1.陣列中重複的數字陣列
- 查詢陣列中出現次數大於陣列長度一半的數字陣列
- [劍之offer] 03 陣列中重複的數字陣列
- 《劍指offer》:[41]陣列中和為S的兩個數陣列
- 劍指Offer-把陣列中的數排成一個最小的數陣列
- (python版)《劍指Offer》JZ06:旋轉陣列的最小數字Python陣列