Given an array of ints with size t, one needs to find the center index. The center index x is the index where the sum of ints (0 to x-1) is equal to sum (x+1 to t-1).
The best algorithm I could come up with is O(n).
I would have a temp array with the sums of all ints before (not including the one at index x) : so at index 1 it would be 1, at 2 it would be a sum of 2 and 1 and so on.
Another int would be the sum of all ints.
I would loop twice through the array, the first make the temp array, and the other to find if both parts are equal.
Is there a better algorithm O(logn)?
Since you have to calculate the sum of both the half of the array, this can't be solved in less than O(n). Because you have to inspect each element at least once (to calculate the sum). Any algorithm can be logn only if we can skip inspecting certain elements of the array based on some condition which is not possible here.
Related
I am solving a problem where I have been given an array A of length N and an integer 0<K<N. We need to make sum of all subarrays(including circular) of length K equal in min operations. In one operation, we can either increment or decrement an element of array by 1.
I am unable to think of an algorithm to do this. For K=1, I can calculate the mean and then calculate the sum of absolute difference between mean and the array elements. But for larger K, can anybody give me a hint?
Hint: the final array should be whole repetitions of the first K elements, like [1,2,3,1,2,3,1,2,3] due to the circular constraint.
Hence if N is not divisible by K, then all elements should be equal, and they should all be changed to the median of the array. If N is even, taking the N/2 or N/2+1 smallest element is the same.
Otherwise, you need to make a[0], a[K], ... equal, a[1], a[K+1], ... equal and so on. Solve them independently by changing each to the corresponding median.
Given an unsorted array of integers.
I'm trying to come up with an efficient solution (better than O(n2)) but the best I can come up with is an O(n2) solution:
for i from 0 to size of list:
sum = list[i]
for j from i + 1 to size of list:
sum += list[j]
if sum % (j - i + 1) == 0:
return true
return false
I've read stuff on sliding window technique, but it looks like that would be useful for subarrays of a specific length k.
This might be a trick question :) Two odd numbers sum to an even number and two even numbers sum to an even number. The only data set that would not include a contiguous subarray of length two that's also divisible by two would have to alternate [..., odd, even, odd, even, ...]. But then the data set would need to be even further restricted to prevent a subarray of length 4 to be divisible by four, since every other even number is divisible by four.
The probability of receiving such a list is extremely small and continues to reduce as the list gets larger (what's more, it lends itself to a subset of numerical patterns; could those be of interest?), which means unless someone worked painstakingly to create some, most if not all real-world situations would find a solution with a sliding window of size 4 that also checks for alternating parity.
Similarity number for two arrays X and Y, each with size N, is defined as the number of pairs of indices (i,j) such that X[i]=Y[j] , for 1<=i,j
Now we are given two arrays, of size N and M. We need to find the number of sub arrays of equal sizes from these two arrays such that the similairty number of each subarray pair is greater or equal to given number K.
Example, say we have N=3, M=3, K=1 and arrays be [1,3,4] and [1,5,3] then here answer is 6
Explanation :
({1},{1})
({3},{3})
({1,3},{1,5})
({1,3},{5,3})
({3,4},{5,3})
({1,3,4},{1,5,3})
so ans = 6
How to solve it for given arrays of size N,M and given integer K.
Number of elements can't be more than 2000. K is also less than N*M
Approach :
Form all subarrays from array 1 of size N, those will be N*(N+1)/2 And same for array 2 of size M. Then try to find similarity number between each subarray pair. But this is very unoptimised way of doing it.
What can be better way to solve this problem ? I think Dynamic programming can be used to solve this. Any suggestions ?
For {1,1,2} and {1,1,3} and K=1
{[1(1)],[1(1)]}
{[1(1)],[1(2)]}
{[1(2)],[1(1)]}
{[1(2)],[1(2)]}
{[1(1),1(2)],[1(1)]}
{[1(1),1(2)],[1(2)]}
{[1(1)],[1(1),1(2)]}
{[1(2)],[1(1),1(2)]}
{[1(1),1(2)],[1(1),1(2)]}
{[1(2),2],[1(2),3]}
{[1(1),1(2),2],[1(1),1(2),3]}
Since the contest is now over, just for the sake of completeness, here's my understanding of the editorial answer there (from which I learned a lot). Let's say we had an O(1) time method to calculate the similarity of two contiguous subarrays, one from each array, of length l. Then, for each pair of indexes, (i, j), we could binary search the smallest l (extending, say to their left) that satisfies similarity k. (Once we have the smallest l, we know that any greater such l also has enough similarity and we can add those counts in O(1) time.) The total time in this case would be O(M * N * log(max (M,N)).
Well, it turns out there is a way to calculate the similarity of two contiguous subarrays in O(1): matrix prefix-sums. In a matrix, A; where each entry, A(i,j), is 1 if the first array's ith element equals the second array's jth element and 0 otherwise; the sum of the elements in A in the rectangle A(i-l, j-l), A(i,j) (top-left to bottom-right) is exactly that. And we can calculate that sum in O(1) time with matrix prefix-sums, given O(M*N) preprocessing.
You are given an array of integers and a number k. The question is to find a subset such that the sum is maximal and smaller than given number k.
I feel like there is a dynamic programming approach to solve this but I am not sure how to solve this problem efficiently.
The simple dynamic programs for this class of problems all use the same basic trick: for each successive prefix of the array, compute the set of its subset sums, depending on the fact that, when the input elements are bounded, this set has many fewer than 2^n elements (for the problem in question, less than 10,000,000 instead of 2^1000). This particular problem, in Python:
def maxsubsetsumlt(array, k):
sums = {0}
for elem in array:
sums.update({sum_ + elem for sum_ in sums if sum_ + elem < k})
return max(sums)
This could be done using the Subset Sum algorithm with a small adaptation. Instead of returning the boolean value from the last (bottom right) cell you search for the first cell with a value of true which indicates that there is a combination of elements that sum up to this particular k_i < k. This k_i is your maximal sum smaller than k. This algorithm has a worst case time and space complexity of O(nk).
I'm having a hard time solving this problem.
A[1..n] is an array of real numbers which is partially sorted:
There are some p,q (1 <= p <= q <=n) so:
A[1] <= ... <= A[p]
A[p] >= ... >= A[q]
A[q] <= ... <= A[n]
How can we find a value in this array in O(lgn)?
(You can assume that the value exists in the array)
Make 3 binary searches: from 1 to p, p to q and q to n. The complexity is still O(logn).
Since we don't know p and q:
You cannot solve this problem in logn time. Assume a case where you have a sorted list of positive numbers with one zero mixed in (p+1=q and A[q]=0). This situation satisfies all the criteria you mentioned. Now, the problem of finding where that zero is located cannot be solved in sub O(n) time. Therefore your problem cannot be solved in O(logn) time.
Despite the "buried zero" worst case already pointed out, I would still recommend implementing an algorithm that can often speed things up, depending on p,q. For example, suppose that you have n numbers, and each increasing and decreasing region has size at least k. Then if you check 2^m elements in your array, including the first and last element and the rest of the elements as equally spaced as possible, starting with m=2 and then iteratively increasing m by 1, eventually you will reach m when you find 3 pairs of consecutive elements (A,B),(C,D),(E,F) from left-to-right out of the 2^m elements that you have checked, which satisfy A < B, C > D, E < F (some pairs may share elements). If my back-of-the-envelope calculation is correct, then the worst-case m you will need to achieve this will have you checking no more than 4n/k elements, so e.g. if k=100 you are much faster than checking all n elements. Then you know everything before A and everything after F are increasing sequences, and you can binary search through them. Now, if m got big enough that you checked at least sqrt(n) elements, then you can finish up by doing a brute-force search between A and F and the overall running time will be O(n/k + sqrt(n)). On the other hand, if the final m had you check fewer than sqrt(n) elements, then you can further increase m until you have checked sqrt(n) elements. Then there will be 2 pairs of consecutive checked elements (A,B),(C,D) that satisfy A < B, C > D, and there will also be 2 pairs of consecutive checked elements (W,X),(Y,Z) later in the array that satisfy W > X, Y < Z. Then everything before A is increasing, everything between D and W is decreasing, and everything after Z is increasing. So you can binary search these 3 regions in the array. The remaining part of the array that you haven't entirely searched through has size O(sqrt(n)), so you can use brute-force search the unchecked regions and the overall running time is O(sqrt(n)). Thus the bound O(n/k + sqrt(n)) holds in general. I have a feeling this is worst-case optimal, but I don't have a proof.
It's solvable in O(log2n).
if at midpoint the slope is decreasing we're in the p..q range.
if at midpoint the slope is increasing, we're either in 1..p or in q..n range.
perform a binary search in 1.. mid point and mid point..n ranges to seek for a value where the slope is decreasing. It will be found only in one of the ranges. Now we know in which of the 1..p and q..n subranges the mid point is located.
repeat the process from (1) for the subrange with the peaks until hitting the p..q range.
find the peaks in the subranges by applying algorithm in Divide and conquer algorithm applied in finding a peak in an array.
perform 3 binary searches in the ranges 1..p, p..q, q..n.
==> Overall complexity is O(log2n).