Hard
Minimum Stability Factor of Array — Python
Full explanation · Time O(nlogn * logr) · Space O(nlogn)
# Time: O(nlogn * logr)
# Space: O(nlogn)
# number theory, binary search, rmq, sparse table, greedy
class Solution(object):
def minStable(self, nums, maxC):
"""
:type nums: List[int]
:type maxC: int
:rtype: int
"""
def gcd(a, b):
while b:
a, b = b, a%b
return a
def binary_search_right(left, right, check):
while left <= right:
mid = left + (right-left)//2
if not check(mid):
right = mid-1
else:
left = mid+1
return right
# RMQ - Sparse Table
# Template: https://github.com/kamyu104/GoogleCodeJam-Farewell-Rounds/blob/main/Round%20D/genetic_sequences2.py3
# Time: ctor: O(NlogN) * O(fn)
# query: O(fn)
# Space: O(NlogN)
class SparseTable(object):
def __init__(self, arr, fn):
self.fn = fn
self.bit_length = [0]
n = len(arr)
k = n.bit_length()-1 # log2_floor(n)
for i in xrange(k+1):
self.bit_length.extend(i+1 for _ in xrange(min(1<<i, (n+1)-len(self.bit_length))))
self.st = [[0]*n for _ in xrange(k+1)]
self.st[0] = arr[:]
for i in xrange(1, k+1): # Time: O(NlogN) * O(fn)
for j in xrange((n-(1<<i))+1):
self.st[i][j] = fn(self.st[i-1][j], self.st[i-1][j+(1<<(i-1))])
def query(self, L, R): # Time: O(fn)
i = self.bit_length[R-L+1]-1 # log2_floor(R-L+1)
return self.fn(self.st[i][L], self.st[i][R-(1<<i)+1])
def check(l):
cnt = 0
i = 0
while i+l-1 < len(nums):
if rmq.query(i, i+l-1) >= 2:
cnt += 1
i += l
else:
i += 1
return cnt > maxC
rmq = SparseTable(nums, gcd)
return binary_search_right(1, len(nums), check)