Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
778 views
in Technique[技术] by (71.8m points)

algorithm - How can I find the minimum index of the array in this case?

We are given an array with n values.

Example: [1,4,5,6,6]

For each index i of the array a ,we construct a new element of array b such that,

b[i]= [a[i]/1] + [a[i+1]/2] + [a[i+2]/3] + ? + [a[n]/(n?i+1)] where [.] denotes the greatest integer function.

We are given an integer k as well.

We have to find the minimum i such that b[i] ≤ k.

I know the brute-force O(n^2) algorithm (to create the array - 'b'), can anybody suggest a better time complexity and way solve it?

For example, for the input [1,2,3],k=3, the output is 1(minimum-index).

Here, a[1]=1; a[2]=2; a[3]=3;

Now, b[1] = [a[1]/1] + [a[2]/2] + [a[3]/3] = [1/1] + [2/2] + [3/3] = 3;

b[2] = [a[2]/1] + [a[3]/2] = [2/1] + [3/2] = 3;

b[3] = [a[3]/1] = [3/1] = 3 (obvious)

Now, we have to find the index i such that b[i]<=k , k='3' , also b[1]<=3, henceforth, 1 is our answer! :-)

Constraints : - Time limits: -(2-seconds) , 1 <= a[i] <= 10^5, 1 <= n <= 10^5, 1 <= k <= 10^9

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's an O(n √A)-time algorithm to compute the b array where n is the number of elements in the a array and A is the maximum element of the a array.

This algorithm computes the difference sequence of the b array (?b = b[0], b[1] - b[0], b[2] - b[1], ..., b[n-1] - b[n-2]) and derives b itself as the cumulative sums. Since the differences are linear, we can start with ?b = 0, 0, ..., 0, loop over each element a[i], and add the difference sequence for [a[i]], [a[i]/2], [a[i]/3], ... at the appropriate spot. The key is that this difference sequence is sparse (less than 2√a[i] elements). For example, for a[i] = 36,

>>> [36//j for j in range(1,37)]
[36, 18, 12, 9, 7, 6, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
>>> list(map(operator.sub,_,[0]+_[:-1]))
[36, -18, -6, -3, -2, -1, -1, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

We can derive the difference sequence from a subroutine that, given a positive integer r, returns all maximal pairs of positive integers (p, q) such that pq ≤ r.

See complete Python code below.

def maximal_pairs(r):
    p = 1
    q = r
    while p < q:
        yield (p, q)
        p += 1
        q = r // p
    while q > 0:
        p = r // q
        yield (p, q)
        q -= 1


def compute_b_fast(a):
    n = len(a)
    delta_b = [0] * n
    for i, ai in enumerate(a):
        previous_j = i
        for p, q in maximal_pairs(ai):
            delta_b[previous_j] += q
            j = i + p
            if j >= n:
                break
            delta_b[j] -= q
            previous_j = j
    for i in range(1, n):
        delta_b[i] += delta_b[i - 1]
    return delta_b


def compute_b_slow(a):
    n = len(a)
    b = [0] * n
    for i, ai in enumerate(a):
        for j in range(n - i):
            b[i + j] += ai // (j + 1)
    return b


for n in range(1, 100):
    print(list(maximal_pairs(n)))

lst = [1, 34, 3, 2, 9, 21, 3, 2, 2, 1]
print(compute_b_fast(lst))
print(compute_b_slow(lst))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...