https://leetcode.com/problems/find-the-index-of-the-large-integer/description/
We have an integer array arr
, where all the integers in arr
are equal except for one integer, which is larger than the rest of the integers. You will not be given direct access to the array. Instead, you will have an API ArrayReader
which have the following functions:
int compareSub(int l, int r, int x, int y)
: where0 <= l, r, x, y < ArrayReader.length()
,l <= r and
x <= y
. The function compares the sum of sub-arrayarr[l..r]
with the sum of the sub-arrayarr[x..y]
and returns:- 1 if
arr[l]+arr[l+1]+...+arr[r] > arr[x]+arr[x+1]+...+arr[y]
. - 0 if
arr[l]+arr[l+1]+...+arr[r] == arr[x]+arr[x+1]+...+arr[y]
. - -1 if
arr[l]+arr[l+1]+...+arr[r] < arr[x]+arr[x+1]+...+arr[y]
.
- 1 if
int length()
: Returns the size of the array.
You are allowed to call compareSub()
20 times at most. You can assume both functions work in O(1)
time.
Return the index of the array arr
which has the largest integer.
Example 1:
Input: arr = [7,7,7,7,10,7,7,7]
Output: 4
Explanation: The following calls to the API
reader.compareSub(0, 0, 1, 1)
// returns 0 this is a query comparing the sub-array (0, 0) with the sub array (1, 1), (i.e. compares arr[0] with arr[1]).
Thus we know that arr[0] and arr[1] doesn’t contain the largest element.
reader.compareSub(2, 2, 3, 3)
// returns 0, we can exclude arr[2] and arr[3].
reader.compareSub(4, 4, 5, 5)
// returns 1, thus for sure arr[4] is the largest element in the array.
Notice that we made only 3 calls, so the answer is valid.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/** * // This is ArrayReader's API interface. * // You should not implement it, or speculate about its implementation * interface ArrayReader { * // Compares the sum of arr[l..r] with the sum of arr[x..y] * // return 1 if sum(arr[l..r]) > sum(arr[x..y]) * // return 0 if sum(arr[l..r]) == sum(arr[x..y]) * // return -1 if sum(arr[l..r]) < sum(arr[x..y]) * public int compareSub(int l, int r, int x, int y) {} * * // Returns the length of the array * public int length() {} * } */ class Solution { public int getIndex(ArrayReader reader) { int length = reader.length(); int lo = 0; int hi = length-1; while(lo<hi){ //calculate length of the subarray; int len = (hi-lo)+1; int mid = lo + (hi-lo)/2; //if the length of the subarray is even if(len%2==0){ int res = reader.compareSub(lo, mid, mid+1, hi); if(res>=0){ hi = mid; } else { lo = mid+1; } } //if the length of the subarray is odd else { //compare lo to mid-1 and mid+1 to hi int res = reader.compareSub(lo, mid-1, mid+1, hi); if(res==0){ return mid; } else if(res == 1) { hi = mid-1; } else { lo = mid+1; } } } return lo; } } |