原題戳我。java
Given a big sorted array with positive integers sorted by ascending order. The array is so big so that you can not get the length of the whole array directly, and you can only access the kth number by ArrayReader.get(k)
(or ArrayReader->get(k)
for C++
). Find the first index of a target number. Your algorithm should be in O(log k), where k is the first index of the target number.git
Return -1, if the number doesn't exist in the array.github
Notice:
If you accessed an inaccessible index (outside of the array), ArrayReader.get will return2147483647
.數組
O(log k), k is the first index of the given target number.less
Sorted Array
Binary Search
ide
這道題我是看題解才作出來的,思路很是好,有兩個重點:優化
第二點無需證實,下面講解第一點。code
若是從0遍歷到k,那麼明顯時間複雜度爲O(k),超過了了O(logk)。ip
要記得,咱們的目的是肯定一個數組的上界r,使O(r)=O(k),繼而在這段數組上進行二分查找,複雜度爲O(logk)。所以,咱們只須要將在O(logk)的時間內找到該r。get
r的要求以下:
即,尋找一個運算,進行O(logk)次,結果爲O(k)。因而想到了乘冪:
2 ** O(logk) = O(k)
代碼以下:
private int[] computeRange(ArrayReader reader, int target){ int r = 1; while (reader.get(r) < target) { r <<= 1; } int l = r >> 1; while (r >= l && reader.get(r) == 2147483647) { r--; } if (r < l) { return null; } return new int[]{l, r}; }
/** * Definition of ArrayReader: * * class ArrayReader { * // get the number at index, return -1 if index is less than zero. * public int get(int index); * } */ public class Solution { /** * @param reader: An instance of ArrayReader. * @param target: An integer * @return : An integer which is the index of the target number */ public int searchBigSortedArray(ArrayReader reader, int target) { // write your code here if (reader == null) { return -1; } if (reader.get(0) > target) { return -1; } int[] range = computeRange(reader, target); if (range == null) { return -1; } int k = bsearchLowerBound(reader, range[0], range[1], target); if (reader.get(k) != target) { return -1; } return k; } private int[] computeRange(ArrayReader reader, int target){ int r = 1; while (reader.get(r) < target) { r <<= 1; } int l = r >> 1; while (r >= l && reader.get(r) == 2147483647) { r--; } if (r < l) { return null; } return new int[]{l, r}; } private int bsearchLowerBound(ArrayReader reader, int l, int r, int v) { while (l < r) { int m = l + (r - l) / 2; if (reader.get(m) >= v) { r = m; } else { l = m + 1; } } return l; } }
本文連接:【刷題】Search in a Big Sorted Array
做者:猴子007
出處:https://monkeysayhi.github.io
本文基於 知識共享署名-相同方式共享 4.0 國際許可協議發佈,歡迎轉載,演繹或用於商業目的,可是必須保留本文的署名及連接。