(4)統計一個數字,在排序陣列中出現的次數
阿新 • • 發佈:2019-02-12
題目描述:統計一個數字K,在排序陣列中出現的次數;
例如:陣列data{1,2,2,3,3,3,3,4} , k = 3 則其出現次數應該為4;
思路一:
順序掃描,若data[i] = k , 計數Number ++;
時間複雜度為O(n);
思路二:
耗費時間主要還是在查詢k上,由於陣列已經排好序,可以利用二分查詢演算法 , 進行查詢;若K= 3,又因為3連續出現;
故直觀的想法就是:如果知道第一個出現的k下標 和最後一個出現的k下標,就很容易知道k出現的次數;
二分查詢:middle , start , end ; middle = (start + end) / 2
若data[middle] = k , 並且 data[middle - 1] != k;;或者 data[middle] = k 且 middle = 0 , 此時那麼此時的middle 即為 k第一次出現的下標
若data[middle] > k , 則 目標k在陣列的前半段,故--> end = middle - 1;
若data[middle] < k , 則目標k在陣列的後半段 , 故-->start = middle + 1;
程式碼實現:
#include<iostream> using namespace std; //----------------------------------------------------------------------------------------------------------------- int GetFirstK(int* data, int length, int k, int start, int end); int GetLastK(int* data, int length, int k, int start, int end); //----------------------------------------------------------------------------------------------------------------- //函式功能:查詢k在目標陣列data[]中的次數 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; } return number; } // 找到陣列中第一個k的下標。如果陣列中不存在k,返回-1 //時間複雜度:O(logn) 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; else end = middleIndex - 1; } else if(middleData > k) end = middleIndex - 1; else start = middleIndex + 1; return GetFirstK(data, length, k, start, end); } // 找到陣列中最後一個k的下標。如果陣列中不存在k,返回-1 //時間複雜度:O(logn) 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; else start = middleIndex + 1; } else if(middleData < k) start = middleIndex + 1; else end = middleIndex - 1; return GetLastK(data, length, k, start, end); }