We have an integer array nums, where all the integers in nums are 0 or
1. You will not be given direct access to the array, instead, you will have an APIArrayReader which have the following functions:
int query(int a, int b, int c, int d): where 0 <= a < b < c < d < ArrayReader.length(). The function returns the distribution of the value of the 4 elements and returns:
4 : if the values of the 4 elements are the same (0 or 1).
2 : if three elements have a value equal to 0 and one element has value equal to 1 or vice versa.
0 : if two element have a value equal to 0 and two elements have a value equal to 1.
int length(): Returns the size of the array.
You are allowed to call query()2 * n times at most where n is equal to
ArrayReader.length().
Return any index of the most frequent value in nums, in case of tie, return -1.
Input: nums =[0,0,1,0,1,1,1,1]Output: 5Explanation: The following calls to the API
reader.length()// returns 8 because there are 8 elements in the hidden array.
reader.query(0,1,2,3)// returns 2 this is a query that compares the elements nums[0], nums[1], nums[2], nums[3]
// Three elements have a value equal to 0 and one element has value equal to 1 or viceversa.
reader.query(4,5,6,7)// returns 4 because nums[4], nums[5], nums[6], nums[7] have the same value.
we can infer that the most frequent value is found in the last 4 elements.Index 2,4,6,7is also a correct answer.
Example 2:
1
2
Input: nums =[0,0,1,1,0]Output: 0
Example 3:
1
2
Input: nums =[1,0,1,0,1,0,1,0]Output: -1
Constraints:
5 <= nums.length <= 10^5
0 <= nums[i] <= 1
Follow up: What is the minimum number of calls needed to find the majority
element?
Since we can only query 4 indices at a time, we can use the result of queries on overlapping sets to deduce which indices are likely to have the same value as the first index. By comparing the results of queries that differ by one index, we can infer whether that index matches the first index or not. We then count the number of indices matching the first index and return any such index if it is the majority, otherwise return -1.
classSolution {
funguessMajority(reader: ArrayReader): Int {
val n = reader.length()
val base = reader.query(0, 1, 2, 3)
var cntSame = 1var cntDiff = 0var idxSame = 0var idxDiff = -1for (i in4 until n) {
val res = reader.query(0, 1, 2, i)
if (res == base) {
cntSame++ idxSame = i
} else {
cntDiff++ idxDiff = i
}
}
for (i in0 until 4) {
val idx = mutableListOf<Int>()
for (j in0 until 4) if (j != i) idx.add(j)
idx.add(4)
val res = reader.query(idx[0], idx[1], idx[2], idx[3])
if (res == base) {
cntSame++ idxSame = i
} else {
cntDiff++ idxDiff = i
}
}
returnwhen {
cntSame > cntDiff -> idxSame
cntDiff > cntSame -> idxDiff
else-> -1 }
}
}
classSolution:
defguessMajority(self, reader: 'ArrayReader') -> int:
n = reader.length()
base = reader.query(0, 1, 2, 3)
cnt_same, cnt_diff =1, 0 idx_same, idx_diff =0, -1for i in range(4, n):
res = reader.query(0, 1, 2, i)
if res == base:
cnt_same +=1 idx_same = i
else:
cnt_diff +=1 idx_diff = i
for i in range(4):
idx = [j for j in range(4) if j != i] + [4]
res = reader.query(*idx)
if res == base:
cnt_same +=1 idx_same = i
else:
cnt_diff +=1 idx_diff = i
if cnt_same > cnt_diff:
return idx_same
if cnt_diff > cnt_same:
return idx_diff
return-1