生活随笔
收集整理的這篇文章主要介紹了
数据结构与算法--数字在排序数组中出现次数
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
數(shù)字在排序數(shù)組中出現(xiàn)次數(shù)
- 題目:統(tǒng)計一個數(shù)字在一個排序數(shù)組中出現(xiàn)的次數(shù)。例如,輸入數(shù)組{1,2,3,3,3,3,3,4,5} 和數(shù)字3,由于3 在數(shù)組中出現(xiàn)的次數(shù)是5,因此返回5
簡單方案一
- 既然輸入的數(shù)組是有序的,那么最簡單的方式是一次遍歷,統(tǒng)計出需要的數(shù)字出現(xiàn)的個數(shù),時間復(fù)雜度是O(n),實現(xiàn)方法如下:
*** 查詢有序數(shù)組中數(shù)字k 出現(xiàn)的次數(shù)
** @author liaojiamin
* @Date:Created in
16:08 2021/6/24*/
public class GetNumberOfK {public static void main(String
[] args
) {int[] array
= new int[]{1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, 33, 44, 55, 56, 56, 56, 56, 56, 57};System
.out
.println(countK(array
, 0));}public static Integer
countK(int[] array
, int k
) {if (array
== null
|| array
.length
<= 0) {return -1;}int count
= 0;for (int i
= 0; i
< array
.length
; i
++) {if (array
[i
] == k
) {count
++;}}return count
;}}
方法二二分查找
- 有序數(shù)組,而且是查詢,那么時間效率最高的就是二分查找了,分析流程如下:
- 如上案例中二分查找找出其中一個3 的位置,標(biāo)記為position
- 此時可能前后都還存在3,那么從position向前遍歷,查找之前的3,得到firstK
- 從position向后遍歷,查找之后的3,得到lastK
- 那么k出現(xiàn)的次數(shù)n = lastK - firstK + 1
- 如上分析有如下代碼:
public class GetNumberOfK {public static void main(String
[] args
) {int[] array
= new int[]{1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, 33, 44, 55, 56, 56, 56, 56, 56, 57};System
.out
.println(binarySearchK(array
, 0));}public static Integer
binarySearchK(int[] array
, int k
) {Integer positionK
= binarySearch(array
, 0, array
.length
- 1, k
);if (positionK
< 0) {return -1;}Integer firstK
= positionK
;Integer lastK
= positionK
;for (int i
= positionK
; i
< array
.length
; i
++) {if (array
[i
] == k
) {lastK
= i
;}}for (int i
= positionK
; i
>= 0; i
--) {if (array
[i
] == k
) {firstK
= i
;}}return lastK
- firstK
+ 1;}public static Integer
binarySearch(int[] array
, int left
, int right
, int k
) {if (array
== null
|| left
< 0 || right
> array
.length
- 1 || left
> right
) {return -1;}int middle
= (left
+ right
) / 2;if (array
[middle
] == k
) {return middle
;}if (array
[middle
] > k
) {return binarySearch(array
, left
, middle
- 1, k
);}if (array
[middle
] < k
) {return binarySearch(array
, middle
+ 1, right
, k
);}return -1;}
}
- 如上算法因為k出現(xiàn)的次數(shù)可能是n次,那么我們向前向后遍歷的次數(shù)可能就是n, 那么時間復(fù)雜度還是O(n),并沒有達到優(yōu)化的目的。此算法中實際主要消耗在如何確定重復(fù)數(shù)字的第一個k與最后一個k的位置上。
方案三純二分查找
public class GetNumberOfK {public static void main(String
[] args
) {int[] array
= new int[]{1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, 33, 44, 55, 56, 56, 56, 56, 56, 57};System
.out
.println(binarySearchAllK(array
, 0));}public static Integer
binarySearchAllK(int[] array
, int k
) {if (array
== null
|| array
.length
<= 0) {return -1;}int firstK
= binarySearchFirstK(array
, 0, array
.length
- 1, k
);int lastK
= binarySearchLastK(array
, 0, array
.length
- 1, k
);if (firstK
< 0 && lastK
< 0) {return -1;}return lastK
- firstK
+ 1;}public static Integer
binarySearchFirstK(int[] array
, int left
, int right
, int k
) {if (array
== null
|| left
< 0 || right
> array
.length
- 1 || left
> right
) {return -1;}int middle
= (left
+ right
) / 2;if (array
[middle
] == k
) {if (middle
- 1 >= left
&& array
[middle
- 1] == k
) {return binarySearchFirstK(array
, left
, middle
- 1, k
);} else {return middle
;}}if (array
[middle
] < k
) {return binarySearchFirstK(array
, middle
+ 1, right
, k
);}if (array
[middle
] > k
) {return binarySearchFirstK(array
, left
, middle
- 1, k
);}return -1;}public static Integer
binarySearchLastK(int[] array
, int left
, int right
, int k
) {if (array
== null
|| left
< 0 || right
> array
.length
- 1 || left
> right
) {return -1;}int middle
= (left
+ right
) / 2;if (array
[middle
] == k
) {if (middle
+ 1 <= right
&& array
[middle
+ 1] == k
) {return binarySearchLastK(array
, middle
+ 1, right
, k
);} else {return middle
;}}if (array
[middle
] > k
) {return binarySearchLastK(array
, left
, middle
- 1, k
);}if (array
[middle
] < k
) {return binarySearchLastK(array
, middle
+ 1, right
, k
);}return -1;}
}
- 如上實現(xiàn)中firstK,lastK都是使用二分查找在數(shù)組中查找,并且二分查找的總量不會大于整個數(shù)組的量n,他們兩次查詢的時間復(fù)雜度都是O(logn),因此總的時間復(fù)雜度就是O(logn),達到了我們優(yōu)化的目的。
上一篇:數(shù)據(jù)結(jié)構(gòu)與算法–最小的k個數(shù)
下一篇:數(shù)據(jù)結(jié)構(gòu)與算法–二叉樹的深度問題
總結(jié)
以上是生活随笔為你收集整理的数据结构与算法--数字在排序数组中出现次数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。