日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

剑指Offer(Java版):数字在排序数组中出现的次数

發布時間:2025/3/20 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 剑指Offer(Java版):数字在排序数组中出现的次数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

題目:統計一個數字在排序數組中出現的次數。例如輸入排序數組為

{1,2,3,3,,3,3,4,5}和數字3,由于3在這個數組中出現了4次,因此輸出4

既然輸入的數組是排序的,那么我們很自然的想到利用二分查找算法。在 題目給出的例子中,我們可以先用二分查找算法找到第一個3.由于3可能出現多次,因此我們找到的3的左右兩遍可能都是3,于是我們在找到3的左右兩邊順序 掃描,分別找出第一個3和最后一個3.因為要查找的數字在長度為n的數組中可能很出現O(n)次,所以順序掃描的時間復雜度為O(n)。因此這種算法的效 率和直接從頭到尾順序掃描整個數組統計3出現的次數的方法是一樣的。顯然,面試官是不會滿意這種算法,它會提示我們還有更快的算法。

接下來我們思考如何更好的利用二分查找算法。假設我們統計數字k在排序數組中出現的次數。在前面的算法的時間主要消耗在如何確定重復出現的第一個k和最后一個k的位置上,有沒有可以利用的二分查找算法直接找到第一個k和最后一個k。

我們先分析如何利用二分查找在數組中找到第一個k,二分查找算法總是 先拿數組的中間的數字和k做比較。如果中間的數字比k大,那么k只能出現在數組的前半段,下一輪我們旨在數組的前半段查找就可以了。如果中間的數字比k 小,那么k只能出現在數組的后半段,下一輪我們只在數組的后半段查找就可以了。如果中間的數字和k相等呢?我們先判斷這個數字是不是第一個k。如果位于中 間數字的前面一個數字不是k,此時中間的數字剛好就是第一個k。如果中間的數字的前面一個數字也是k,也就是說第一個k肯定在數組的前半段,下一輪我們仍 然需要在數組的前半段查找。

同理我們利用上面的思路找到最后一個k。

找到第一個k和最后一個k后就可以知道k出現的次數了,

實現代碼如下:

?

package cglib;

public class jiekou {

?? ?//遞歸找到排序數組中第一個k
?? ? private int getFirstK(int[] arr,int k,int left,int right){ ?
?? ???????? if(left > right) ?
?? ???????????? return -1; ?
?? ???????? int middleIndex = (left+right)/2; ?
?? ???????? int middleData = arr[middleIndex]; ?
?? ???????? if(middleData == k){ //如果中位數等于k
?? ???????????? if((middleIndex >0 && arr[middleIndex -1]!=k)|| middleIndex == 0) ?
?? ???????????????? return middleIndex; //中位數是第一個k ?
?? ???????????? else ?
?? ???????????????? right = middleIndex -1;? //中位數不是第一個k,則往中位數左邊找第一個k
?? ???????? } ?
?? ???????? else if(middleData > k)//中位數大于k ,則第一個k肯定在中位數左邊
?? ???????????? right = middleIndex -1;? //往中位數左邊找第一個k
?? ???????? else ?
?? ???????????? left = middleIndex +1; //中位數小于k ,則第一個k肯定在中位數右邊
?? ???????? return getFirstK(arr,k,left,right); //遞歸
?? ???? } ?
?? ???? //相同的思路,遞歸找到最后的一個k
?? ???? private int getLastK(int[] arr,int k,int left,int right){ ?
?? ???????? if(left > right) ?
?? ???????????? return -1; ?
?? ???????? int middleIndex = (left + right)/2; ?
?? ???????? int middleData = arr[middleIndex]; ?
?? ???????? if(middleData == k){ ?
?? ???????????? if((middleIndex <arr.length -1 && arr[middleIndex+1]!=k) || middleIndex ==arr.length-1) ?
?? ???????????????? return middleIndex; ?
?? ???????????? else ?
?? ???????????????? left = middleIndex+1;? //中位數不是最后一個k,則往中位數右邊找最后個k
?? ???????? } ?
?? ???????? else if(middleData <k){//中位數小于k,則往中位數右邊找最后一個k ?
?? ???????????? left = middleIndex +1; ?
?? ???????? }else ?
?? ???????????? right = middleIndex -1;? //中位數大于k,則往中位數左邊找最后一個k
?? ???????? return getLastK(arr,k,left,right); //遞歸 ?
?? ???? } ?
?? ?? //計算出k在數組中出現的次數
?? ???? public int getNumberOfK(int[] arr,int k){ ?
?? ???????? int number = 0; ?
?? ???????? if(arr.length >0){ ?
?? ???????????? int first = getFirstK(arr,k,0,arr.length-1); ?
?? ???????????? int last = getLastK(arr,k,0,arr.length -1); ?
?? ???????????? if(first >-1 && last >-1) ?
?? ???????????????? number =last-first+1; ?
?? ???????? } ?
?? ???????? return number; ?
?? ???? } ?
?? ???? public static void main(String[] args){ ?
?? ???????? int[] arr= {1,2,3,3,3,3,4,5}; ?
?? ???????? jiekou test = new jiekou(); ?
?? ???????? System.out.println(test.getNumberOfK(arr, 3)); ?
?? ???? }
?? ?}
???

輸出:4

轉載于:https://my.oschina.net/u/2822116/blog/726222

總結

以上是生活随笔為你收集整理的剑指Offer(Java版):数字在排序数组中出现的次数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。