數字在排序陣列中出現的起始索引號

2021-06-24 18:01:49 字數 2246 閱讀 7396

題目如下:

給定乙個公升序的整數陣列,查詢某乙個值在陣列中出現的索引號,例如,輸入陣列2,3,3,4,4,5;查詢的數是3,則返回1,2。時間複雜度要求為o(logn)。

初次拿到這個題目可以立即想到用二分查詢來做,先比較中間的數和要查詢的數,如果關鍵字(要查詢的數)小於中間的數,那麼在陣列的左半部分繼續查詢,如果關鍵字大於中間的數,那麼在陣列的右半部分繼續查詢,如果關鍵字和中間的數相等,那麼先比較中間數字的前乙個數字是否和關鍵字相等,如果相等,繼續用關鍵字和前乙個數字的前乙個數字比較,如果不等,那麼當前數字就是要查詢的數字,其所在的索引就是第一次出現的地方。對於結束的索引,可以用類似的方法來做,先比較中間數字的後乙個數字是否和關鍵字相等,如果相等,繼續用關鍵字和後乙個數字的後乙個數字比較,如果不等,那麼當前數字就是要查詢的數字,其所在的索引就是最後一次出現的地方。但是這樣做,最壞的情況下,時間複雜度會退化為o(n),即當陣列是同乙個數的時候。所以這種方法不是時間上最優的。

其實,本題目是二分查詢的變種,我們可以分為兩步來做,第一步,求得該數字第一次出現的索引,第二步,求得該數字最後一次出現的索引。

首先來看第一次出現的索引怎麼來求,首先比較中間的數和要查詢的數,如果關鍵字(要查詢的數)小於中間的數,那麼在陣列的左半部分繼續查詢,如果關鍵字大於中間的數,那麼在陣列的右半部分繼續查詢,如果關鍵字和中間的數相等,那麼比較中間數字的前乙個數字是否和關鍵字相等,如果不相等,那麼當前的中間索引就是第一次出現的索引,如果相等,那麼繼續在前半部分查詢。具體的實現**如下:

//尋找開始索引

int getfirsttarget(int a, int n, int target,int nstart,int nend)

//中間索引

int nmid = nstart + ( (nend-nstart) >> 1);

int nmiddata = a[nmid];

while (nstart <= nend)

else if (target < nmiddata)

else if (target == nmiddata)

else

nend = nmid-1;

} //更新中間值得索引和值

nmid = nstart + ( (nend-nstart) >> 1);

nmiddata = a[nmid];

} return -1;

}

尋找最後一次出現的索引也可以用類似的思路來做:首先比較中間的數和要查詢的數,如果關鍵字(要查詢的數)小於中間的數,那麼在陣列的左半部分繼續查詢,如果關鍵字大於中間的數,那麼在陣列的右半部分繼續查詢,如果關鍵字和中間的數相等,那麼比較中間數字的

後乙個數字是否和關鍵字相等,如果不相等,那麼當前的中間索引就是

最後一次出現的索引,如果相等,那麼繼續在

後半部分查詢。尋找第乙個索引和最後乙個索引的具體差別可以注意紅色字型的字眼,具體的實現**如下:

//尋找結束索引

int getsecondtarget(int a, int n, int target,int nstart,int nend)

//中間索引

int nmid = nstart + ( (nend-nstart) >> 1);

int nmiddata = a[nmid];

while (nstart <= nend)

else if (target < nmiddata)

else if (target == nmiddata)

else

nstart = nmid+1;

} //更新中間值得索引和值

nmid = nstart + ( (nend-nstart) >> 1);

nmiddata = a[nmid];

} return -1;

}

最後就是主功能函式進行呼叫了,其**如下:

vectorsearchrange(int a, int n, int target)

vecindex[0] = getfirsttarget(a,n,target,0,n-1);

vecindex[1] = getsecondtarget(a,n,target,0,n-1);

return vecindex;

}

兩次查詢的時間複雜度都是o(logn),所以總的時間複雜度就是o(logn)。

最後,這個題目還有另外乙個變種就是數字在排序陣列中出現的次數

數字在排序陣列中出現次數

統計乙個數字在排序陣列中出現的次數。思路 求乙個數字在這個排序陣列中出現的次數,首先想到的是使用二分查詢,當我找到乙個位置,然後往前就可以到達最前面第乙個出現該數字的位置,往後就可以到達最後面最後乙個出現該數字的位置,然後兩個位置相減此時就得到該數字出現的次數。但是問題在於我用二分查詢到位置後,然後...

數字在排序陣列中出現的次數

何海濤 劍指offer 名企面試官精講典型程式設計題 九度oj 題目描述 統計乙個數字在排序陣列中出現的次數。輸入 每個測試案例包括兩行 第一行有1個整數n,表示陣列的大小。1 n 10 6。第二行有n個整數,表示陣列元素,每個元素均為int。第三行有1個整數m,表示接下來有m次查詢。1 m 10 ...

數字在排序陣列中出現的次數

題目 統計乙個數字下排序陣列中出現的次數。例如輸入排序陣列和數字3,由於3在這個陣列中出現了4次,因此輸出4。當然第一眼就能想到遍歷這個陣列然後統計這個陣列中某個數字出現的次數。當然第一眼就能想到的方法通常來說效率都不怎麼樣 再稍微想一下這個題目,是乙個已序的陣列,所以呢,不難想到二分查詢。我們可以...