This is not possible with the restrictions you specified. The best difficulty you can theoretically achieve is O (n).
O () accepts the worst case (just a definition, you can refuse this part). And in the worst case, you will always have to look at each element to check that it is equal to its index.
The case changes if you have more restrictions (for example, numbers are all int and none can appear more than once, i.e. there are no two consecutive numbers). Maybe this is so?
EDIT:
Having heard that my alleged limitations are actually applied (for example, only once), I propose this approach: we can safely assume that you can have only one continuous range, where all your relevant records are located. I. e. you only need to find the lower bound and the upper bound. Then the desired result will be the size of this range.
Each boundary can be safely found using binary search, each of which has O (log n).
def binsearch(field, lower=True, a=0, b=None): if b is None: b = len(field) while a + 1 < b: c = (a + b) / 2 if lower: if field[c] < c: a = c else: b = c else:
I used this for testing:
field = list({ random.randint(-10, 30) for i in range(30) }) field.sort() upper = binsearch(field, lower=False) lower = binsearch(field, b=upper+1) for i, f in enumerate(field): print lower <= i <= upper, i == f, i, f
Alfe
source share