Prove that all prefix sums are non negative [closed] - arrays

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
We have an array having n integers whose sum is non negative.
I need to prove that there exists an index i, such that starting from i, all prefix sums are non negative, till we reach i again circularly.
Say the array is a1, a2, a3, ..... , an, such that a1 + a2 + a3 + ..... + an>=0.
So we need to prove that for some index i, all prefix sums are non-negative, i.e,
ai >= 0,
ai + ai+1 >=0,
ai + ai+1 + ai+2 >=0
.
.
ai + ai+1 + ... + an + a1 + .... + ai-1 >=0
I need this for the following question, https://www.interviewbit.com/problems/gas-station/. Though I've already used the above statement in the solution of this question, but I am still not able to prove it.

Suppose we repeat the array multiple times and then construct the prefix sums of this repeated array. The prefix sums will have the same pattern, except each repetition is higher by an amount equal to the sum of the array.
Consider the index x where the prefix sum is the smallest. This will occur within the first n samples (if the sum of the array is positive).
If you start computing prefix sums from this position x, then all subsequent prefix sums will be non-negative by construction.

Given the premise that you need to prove that there exists at least 1 index for which the property holds, I would propose the opposite to be true (i.e. for every index it holds that at least one prefix sum is negative), then deduce a contradiction implicating that it must be true that at least one index holds this property.

Across all pairs of indices {j, k} there exists one such pair with minimal (maximially negative) sum(j, k). Set i = k+1.
If there exists some sequence a(i), a(i+1), ... a(i+n) for n not in the range {j...k} such that sum(i, n) is negative (i.e., a negative prefix sum), then that would mean sum(j, n) < sum(j, k), which contradicts our initial statement. (This is true because sum (j, n) = sum (j, k) + sum (k+1, n) = sum(i, n), and we claim sum (i, n) to be negative.)
If there exists some n in the range {j...k} such that sum(a, n) is negative, then that means that sum(k+1, j-1) + sum(j, n) < 0. As we know the complete sum to be positive, sum(k+1, j-1) + sum (j, k) > 0 (as that includes all elements.) Therefor sum(j, n) < sum(j, k), which contradicts our initial constraint.
QED

Related

Maximum possible integer x, such that sum of every element of array divided by x is not less than k

We are given an array of n integers, and a constant value k, can any one
suggest me to find out the maximum possible integer x such that arr[0]/x + arr[1]/x +.. arr[n-1]/x >=k ,
-> where '/' is the integer division
-> sum of all elements of array >= k
-> k is a constant(1<=k<=10^5)
-> 1<=n<=10^5.
e.g. n=5, k=3
arr=[1,1,1,8,8]
answer-> x=4
in something like o(N log N) ?
Here is an algorithm that often meets your bound on time efficiency. I assume that your array values are non-negative. The algorithm depends on these facts:
Your objective function arr[0]/x + arr[1]/x +.. arr[n-1]/x (let's call it f(x)) is a decreasing function of x. In other words, if x increases then f(x) will stay the same or decrease.
f(1) equals the sum of the elements of the array, so f(1) >= k. In other words, at x = 1 the objective function is not below the target value k.
If M is set to the maximum array value, the value of arr[i] // (M + 1) is zero, so f(M + 1) = 0. In other words, at x = M + 1 the objective is below the target value k.
So we have upper and lower bounds on the value of x for a decreasing function. We can therefore do a binary search from 1 to M + 1 for the value of x where
f(x) >= k and f(x + 1) < k
Only one value of x will satisfy that, and a binary search can easily find it. The binary search will take log(M) steps. Each step involves one evaluation of f(x) which takes N steps to use each array member. Thus the overall time efficiency is O(N log(M)). If M (the maximum array value) is of the order of N then that is your desired efficiency. At the limiting values you give for N and the array values, we have M < N^2, so N log(M) < 2 N log(N) and your desired efficiency is still met. If N is small and M is large, your desired efficiency is not met. (This means an array like [10^9, 10^9-1] where N = 2 and M = 10^9 which could take 30 steps in the binary search.) This may or may not meet your needs.

Finding period of a sequence

I want to solve this problem:
For a given sequence, a[0], a[1], a[2],..., a[n-1], please find "period" of the sequence.
The period is the minimum integer k (k >= 1) that satisfies a[i] = a[i+k] for all valid i, and also k is a divisor of n.
My current solution is calculating all divisor of n (this is k) and test for all k, but it takes O(n * d(n)). I think it is slow.
Is there any efficient algorithm?
Apply Z-algorithm ( here and here) to given sequence.
Then find the first position i such that
i+z[i] = n
and
n mod i = 0
If such value of i exists, it is the shortest period

Finding the probability that two items are compared. (hints please)

I'm attempting to solve the following problem (from Prof. Jeff Erikson's notes): Given the algorithm below which takes in an unsorted array A and returns the k-th smallest element in the array (given that Partition does what its name implies via the standard quicksort method given the pivot returned by Random (which is assumed to return a uniformly random integer between 1 and n in linear time) and returns the new index of the pivot), we are to find the exact probability that this algorithm compares the i-th smallest and j-th smallest elements in the input array.
QuickSelect(A[1..n],k):
r <-- Partition(A[1..n],Random(n))
if k < r:
return QuickSelect(A[1..r-1],k)
else if k > r:
return QuickSelect(A[r+1..n],k-r)
else:
return A[k]
Now, I can see that the probability of the first if statement being true is (n-k)/n, the probability of the second block being true is (k-1)/n, and the probability of executing the else statement is 1/n. I also know that (assuming i < j) the probability of i < r < j is (j-i-1)/n which guarantees that the two elements are never compared. On the other hand, if i==r or j==r, then i and j are guaranteed to be compared. The part that really trips me up is what happens if r < i or j < r, because whether or not i and j are compared depends on the value of k (whether or not we are able to recursively call QuickSelect).
Any hints and/or suggestions would be greatly appreciated. This is for homework, so I would rather not have full solutions given to me so that I may actually learn a bit. Thanks in advance!
As it has already been mentioned Monte Carlo method is simple solution for fast (in sense of implementation) approximation.
There is a way to compute exact probability using dynamic programming
Here we will assume that all elements in array are distinct and A[i] < A[j].
Let us denote P(i, j, k, n) for probability of comparison ith and jth elements while selecting k-th in an n-elements array.
Then there is equal probability for r to be any of 1..n and this probability is 1/n. Also note that all this events are non-intersecting and their union forms all the space of events.
Let us look carefully at each possible value of r.
If r = 1..i-1 then i and j fall into the same part and the probability of their comparison is P(i-r, j-r, k-r, n-r) if k > r and 0 otherwise.
If r = i the probability is 1.
If r = i+1..j-1 the probability is 0.
If r = j the probability is 1 and if r = j+1..n the probability is P(i, j, k, r-1) if k < r and 0 otherwise.
So the full recurrent formula is P(i, j, k, n) = 1/n * (2 + Sum for r = 1..min(r, i)-1 P(i-r, j-r, k-r, n-r) + sum for r = max(j, k)+1..n P(i, j, k, r-1))
Finally for n = 2 (for i and j to be different) the only possible Ps are P(1, 2, 1, 2) and P(1, 2, 2, 2) and both equal 1 (no matter what r is equal to there will be a comparison)
Time complexity is O(n^5), space complexity is O(n^4). Also it is possible to optimize calculations and make time complexity O(n^4). Also as we only consider A[i] < A[j] and i,j,k <= n multiplicative constant is 1/8. So it would possible to compute any value for n up to 100 in a couple of minutes, using straight-forward algorithm described or up to 300 for optimized one.
Note that two positions are only compared if one of them is the pivot. So the best way to look at this is to look at the sequence of chosen pivots.
Suppose the k-th smallest element is between i and j. Then i and j are not compared if and only if an element between them is selected as a pivot before i or j are. What is the probability that this happens?
Now suppose the k-th smallest element is after j. i and j are not compared if and only if an element between i+1 and k (excluding j) is selected as a pivot before i or j are. What is the probability that this happens?

Modify subset sum [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
Given a array of N positive integers. Let the minimum element be L and sum of all elements is S.
I need to find out if, for each integer X,(where X is between L and S inclusive) can a subset of the array be chosen such that the sum of elements in this subset is equal to X.
EXAMPLE :
Let N=5 and array is {4,8,2,1,16} . Then here all elements can be made between 1 to 31 so here ans is "yes".
If suppose N=4 and array is {5,1,2,7} . Then for values between 1 and 15 the values 4 and 11 cannot be made. So answer here is "no".
I know to find the minimum number that cant be returned by this array,But dont know to how to solve this problem
First, does the array have only one element? If so, the answer is yes.
Otherwise, find the minimum impossible sum. Is it greater than S? If so, the answer is yes. Otherwise, the answer is no. (If the minimum is less than L, the array doesn't contain 1, and S-1 is an impossible sum.)
To find the lowest impossible sum, we sort the input, then find the lowest impossible sum of each prefix of the array. In Python:
def lowest_impossible_sum(nums):
nums = sorted(nums)
partial_sum = 0
for num in nums:
if num > partial_sum + 1:
return partial_sum + 1
partial_sum += num
return partial_sum + 1
Proof of correctness by induction:
Let A be the sorted array. If A[0] > 1, then 1 is the lowest impossible sum. Otherwise, the elements of A[:1] can produce all sums up to sum(A[:1]).
Suppose for induction that subsets of A[:k] can be selected to produce all sums up to sum(A[:k]).
If A[k] > sum(A[:k]) + 1, then sum(A[:k]) + 1 is the lowest impossible sum; it can't be produced by a subset of A[:k], and adding elements that aren't in A[:k] won't help, as they're all too big.
If A[k] <= sum(A[:k]) + 1, then subsets of A[:k+1] can produce every sum up to sum(A[:k+1]). Every sum up to sum(A[:k]) can already be produced by the inductive hypothesis, and sums from sum(A[:k]) + 1 to sum(A[:k+1]) can be produced by selecting A[k] and a suitable subset of A[:k] adding up to what's left.
Let x be the first index such that A[x] > sum(A[:x]) + 1, or len(A) if there is no such index. By induction, every sum up to sum(A[:x]) is possible. However, whether because x is past the end of the array or because A[x] > sum(A[:x]) + 1, it is impossible to produce the sum sum(A[:x]) + 1. Thus, we need merely search for x and return sum(A[:x]) + 1. That is what the algorithm does.
First sort all elements in the array. If you want to get all the values between L and S from the elements of the array, then L = 1 and the elements should be in the form of 2^i . And the greatest element may not be of form 2^i because the sum need not be of the form (2^i - 1).

Subinterval of length >= k in an array, with maximum average [duplicate]

From an integer array A[N], I'd like to find an interval [i,j] that has a maximized average (A[i] + A[i + 1] + .. + A[j]) / (j - i + 1).
The length of the interval (j - i + 1) should be more than L.(L >= 1)
What I thought was to calculate an average for every i ~ j, but it is too slow to do like this.(N is too big)
Is there an algorithm faster than O(N^2)? Or I'd like to know whether there exists a randomized method for that.
There is an O(N*logC) algorithm, where C is proportional to the maximum element value of the array. Comparing with some more complicated algorithms in recent papers, this algorithm is easier to understand, and can be implemented in a short time, and still fast enough in practical.
For simplicity, We assume there is at least one non-negative integers in the array.
The algorithm is based on binary search. At first, we can find that the final answer must be in the range [0, max(A)], and we half this interval in each iteration, until it is small enough (10-6 for example). In each iteration, assume the available interval is [a,b], we need to check whether the maximum average is no less than (a+b)/2. If so, we get a smaller interval [(a+b)/2, b], or else we get [a, (a+b)/2].
Now the problem is: Given a number K, how to check that the final answer is at least K?
Assume the average is at least K, there exist some i, j such that (A[i] + A[i+1] + ... + A[j]) / (j - i + 1) >= K. We multiply both sides by (j-i+1), and move the right side to left, and we get (A[i] - K) + (A[i+1] - K) + ... + (A[j] - K) >= 0.
So, let B[i] = A[i] - K, we only need to find an interval [i, j] (j - i + 1 > L) such that B[i] + ... + B[j] >= 0. Now the problem is: Given array B and length L, we are to find an interval of maximum sum whose length is more than L. If the maximum sum is >= 0, the original average number K is possible.
The second problem can be solved by linear scan. Let sumB[0] = 0, sumB[i] = B[1] + B[2] + ... + B[i]. For each index i, the max-sum interval which ended at B[i] is sumB[i] - min(sumB[0], sumB[1], ..., sumB[i-L-1]). When scanning the array with increasing i, we can maintain the min(sumB[0], ..., sumB[i-L-1]) on the fly.
The time complexity of the sub-problem is O(N). And we need O(logC) iterations, so the total complexity is O(N*logC).
P.s. This kinds of "average problem" belongs to a family of problems called fractional programming. The similar problems are minimum average-weighted spanning tree, minimum average-weighted cycle, etc.
P.s. again. The O(logC) is a loose bound. I think we can reduce it by some careful analysis.

Resources