多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > 互聯網 > 數字在排序數組中出現的起始索引號

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

來源:程序員人生   發布時間:2014-09-03 12:32:27 閱讀次數:3287次

題目如下:

給定一個升序的整數數組,查找某一個值在數組中出現的索引號,例如,輸入數組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) { if (nStart > nEnd) { return -1; } //中間索引 int nMid = nStart + ( (nEnd-nStart) >> 1); int nMidData = A[nMid]; while (nStart <= nEnd) { if (target > nMidData) { nStart = nMid+1; } else if (target < nMidData) { nEnd = nMid-1; } else if (target == nMidData) { if ((target != A[nMid-1] && nMid > 0) || nMid == 0) { return nMid; } 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) { if (nStart > nEnd) { return -1; } //中間索引 int nMid = nStart + ( (nEnd-nStart) >> 1); int nMidData = A[nMid]; while (nStart <= nEnd) { if (target > nMidData) { nStart = nMid+1; } else if (target < nMidData) { nEnd = nMid-1; } else if (target == nMidData) { if ((target != A[nMid+1] && nMid < n) || nMid == n-1) { return nMid; } else nStart = nMid+1; } //更新中間值得索引和值 nMid = nStart + ( (nEnd-nStart) >> 1); nMidData = A[nMid]; } return -1; }

最后就是主功能函數進行調用了,其代碼如下:

vector<int> searchRange(int A[], int n, int target) { std::vector<int> vecIndex; vecIndex.resize(2); vecIndex[0] = -1; vecIndex[1] = -1; if (A == NULL || n <= 0) { return vecIndex; } vecIndex[0] = GetFirstTarget(A,n,target,0,n-1); vecIndex[1] = GetSecondTarget(A,n,target,0,n-1); return vecIndex; }


兩次查找的時間復雜度都是O(logN),所以總的時間復雜度就是O(logN)。

最后,這個題目還有另外一個變種就是數字在排序數組中出現的次數

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 成人青草亚洲国产 | 中文成人在线 | 国内性经典xxxxx | 性免费视频 | 五月天国产视频 | 免费一级在线观看 | 一二三四视频在线6 1免费观看 | 精品国产一区二区三区久 | 在线成人小视频 | 免费看一级毛片欧美 | 岛国午夜视频 | 国产成人亚洲精品无广告 | 爱爱综合 | 麻豆国产免费看片在线播放 | 亚洲线精品一区二区三区 | 欧美末成年videos在线 | 欧美日韩精品乱国产 | 色妞在线影院色 | 亚洲欧洲春色校园另类小说 | 天堂最新版在线www在线 | 尤物精品在线观看 | 97影院午夜在线观看琪琪 | 久久久亚洲欧美综合 | 亚洲免费看片 | 亚州色片 | 色欧美综合 | 亚洲成人看片 | 精品久久久久久 | 国内视频自拍在线视频 | 日本一区视频在线播放 | 小说亚洲| 国内精品免费视频精选在线观看 | 韩日一区二区三区 | 中文字幕在线观看一区二区三区 | 看黄网址 | 激情在线观看视频 | 在线观看国产福利 | 欧美成视频一theporn | 午夜高清免费观看视频 | 国产小片 | 欧美人马交 |