Consider an array of N integers. Find the longest contiguous subarray so that the average of its elements is greater (or equal) than a given number k.
The obvious answer has O(n^2) complexity. Can we do better?
We can reduce this problem to longest contiguous subarray with sum >= 0 by subtracting k from all values in O(n) time. Now let's calculate prefix sums:
index 0 1 2 3 4 5 6
array 2 -3 3 2 0 -1
prefix 0 2 -1 2 5 5 4
Now this problem is finding the two indices most far apart with prefix_right - prefix_left >= 0. Let's create a new prefix-index array and sort it by prefix, then indices.
index 2 0 1 3 6 4 5
prefix -1 0 2 2 4 5 5
We can then do a right-to-left sweep to calculate, for each prefix, the maximum index with prefix greater than or equal to the current prefix:
index 2 0 1 3 6 4 5
prefix -1 0 2 2 4 5 5
maxind 6 6 6 6 6 5 5
Now, let's go back to the original prefix array. For each prefix-index pair, we do a binary search on our new array to find the smallest prefix >= the current prefix. We subtract, from maxind of the binary searched prefix, the index of the current prefix to retrieve the best possible sequence length starting at the current index. Take the sequence with the maximum length.
This algorithm is O(n log n) because of the sorting and the n binary searches.
We can solve problem in O(n) time and O(n) space complexity:
I have tried with naive and optimal approach.
In short, the problem involves two steps:
(1) Subtract k from each ar[i] and find cumulative value in new array. Lets call the new array as cumArr[].
(2) Now the problem becomes finding max(j-1) in CumArr[] such that j>i and cumArr[j]>cumArr[i]. This step is a famous question and can be found at lots of places.
Here is the detail with running code:
http://codeshare.io/Y1Xc8
There might be small corner cases which can be handled easily.
Let me know your thoughts friends.
Related
You are given an array of n elements you allowed to delete at max one element from provided array. The order of elements remain the same .you are required to maximize the number of subarrays that contain both maximum and minimum element of the resultant array . A subarrays is the sequence of consecutive element of the array
Input
T no of test case
N size of array
N array element
Output
For each test case print one single integer the maximum number of subarrays that contains both maximum and minimum elements of the resultant array
Examples
4
6
7 2 5 4 3 1
7
1 2 3 4 5 6 7
6
2 5 3 2 5 5
4
5 5 5 5
Output
4
1
12
15
Test case 1 explanation
If we delete 1 from the array then the resultant array will be 7 2 5 4 3
So the number of subarrays will contains max 7 and minimum 2 will be 4
[7,2]
[7,2,5]
[7,2,5,4]
[7,2,5,4,3]
Do some math. If the min and max elements are at the indices i and j (does not matter who is where, just i < j), the number of subarrays is (i + 1) * (len - j). Prove this fact, or at least convince yourself that it is so.
Now, prove (or at least convince yourself) that it doesn't make sense to remove any element other than min or max.
I hope that this is enough to get you started.
I'm solving a problem which requires to sort an array. An array with size n can contain elements from 1 to n.
We are given an array and m number of swaps. we have to sort that array by using given swaps and own swap, in such a way we use minimum of own swaps...
Example..
Array 3 1 4 2
Given swaps 1 2
Here first we can perform given swap...array become 1 3 4 2 now we can use own swaps 2 ,4 and 3, 4...(1,2 and 3,4 are indexes)
So answer here is 2 because only own swaps are counted and we need to minimise it
Array example: 8 8 1 1 4 6 6 2 2 9 9 =>result: 4
Is it even possible in less then O(n), like O(logn)? The person who gave this to me said it was possible. I need an answer in within 12 hrs.
yes it's possible with O(lg n)
we know the size of array is 2n+1, and n is the middle of array
Search(A)
if A[n] is not equal to it's adjacent, it's the answer
else
find the equal adjacent to A[n]
if(n is even)
search within the half array that is equal to A[n]
if n is odd
search within the half array that is not equal to A[n]
in you example:
8 8 1 1 4 6 6 2 2 9 9, n is 5
n
A[n] is equal to it's right adjacent, n is odd so we search in the left half
8 8 1 1 4 , n is 2
n
A[n] is equal to it's right adjacent , n is even, so we search in right half
and etc
This is the classic finding a local maximum (just one) in a matrix.
My algorithm is:
Choose the number in the center of the matrix.
Check if the number is a peak. If yes, return.
If not, check the numbers to the left and right. If one of them is greater than our current number, choose that half of the matrix. If both are greater, we can choose either half.
Repeat with the numbers to the top and bottom. This will leave us with one quadrant of the matrix to continue checking.
Since this is binary search for a n x n matrix which has n^2 elements, it should take O(log(n^2)) = O(2*log(n)) = O(log(n))
I'm pretty sure this is not correct, but where is my mistake?
This algorithm isn't guaranteed to find the local maximum. Consider for example the case where you need to follow a winding path through the matrix of ascending values to get to the peak. If that path crosses back and forth between quadrants you algorithm will not find it.
13 1 1 1 1
12 1 1 1 1
11 1 1 2 3
10 1 1 1 4
9 8 7 6 5
Or, here's a simpler example:
3 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
You start in the middle, how do you find the '3'? You algorithm doesn't describe what to do when faced with a horizontal plane.
Consider reading Find a peak element in a 2D array, where it describes a brute force approach, as well as an efficient method which has a time complexity of O(rows * log(columns)), in yout case O(nlogn).
The algorithm is based on Binary Search, thus the logn term you had in your complexity too:
Consider mid column and find maximum element in it.
Let index of mid column be ‘mid’, value of maximum element in mid
column be ‘max’ and maximum element be at ‘mat[max_index][mid]’.
If max >= A[index][mid-1] & max >= A[index][pick+1], max is a peak,
return max.
If max < mat[max_index][mid-1], recur for left half of matrix.
If max < mat[max_index][mid+1], recur for right half of matrix.
However, your algorithm won't work for all cases, and might fail to find a local maximum, since you only look neighboring elements of the current center, which does not guarantee you that will find the maximum (the elements are not sorted of course). Example:
1 1 1 1 1
1 1 1 1 1
1 2 1 1 1
1 1 1 1 1
1 1 1 1 10
You start from the center, you pick the wrong submatrix, you are doomed not to find the local maximum.
I'm looking for an algorithm that generates all permutations of a set. To make it easier, the set is always [0, 1..n]. There are many ways to do this and it's not particularly hard.
What I also need is the number of inversions of each permutation.
What is the fastest (in terms of time complexity) algorithm that does this?
I was hoping that there's a way to generate those permutations that produces the number of inversions as a side-effect without adding to the complexity.
The algorithm should generate lists, not arrays, but I'll accept array based ones if it makes a big enough difference in terms of speed.
Plus points (...there are no points...) if it's functional and is implemented in a pure language.
There is Steinhaus–Johnson–Trotter algorithm that allows to keep inversion count easily during permutation generation. Excerpt from Wiki:
Thus, from the single permutation on one element,
1
one may place the number 2 in each possible position in descending
order to form a list of two permutations on two elements,
1 2
2 1
Then, one may place the number 3 in each of three different positions
for these three permutations, in descending order for the first
permutation 1 2, and then in ascending order for the permutation 2 1:
1 2 3
1 3 2
3 1 2
3 2 1
2 3 1
2 1 3
At every step of recursion we insert the biggest number in the list of smaller numbers. It is obvious that this insertion adds M new inversions, where M is insertion position (counting from the right). For example, if we have 3 1 2 list (2 inversions), and will insert 4
3 1 2 4 //position 0, 2 + 0 = 2 inversions
3 1 4 2 //position 1, 2 + 1 = 3 inversions
3 4 1 2 //position 2, 2 + 2 = 4 inversions
4 3 1 2 //position 3, 2 + 3 = 5 inversions
pseudocode:
function Generate(List, Count)
N = List.Length
if N = N_Max then
Output(List, 'InvCount = ': Count)
else
for Position = 0 to N do
Generate(List.Insert(N, N - Position), Count + Position)
P.S. Recursive method is not mandatory here, but I suspect that it is natural for functional guys
P.P.S If you are worried about inserting into lists, consider Even's speedup section that uses only exchange of neighbour elements, and every exchange increments or decrements inversion count by 1.
Here is an algorithm that does the task, is amortized O(1) per permutation, and generates an array of tuples of linked lists that share as much memory as they reasonably can.
I'll implement all except the linked list bit in untested Python. Though Python would be a bad language for a real implementation.
def permutations (sorted_list):
answer = []
def add_permutations(reversed_sublist, tail_node, inversions):
if (0 == len(sorted_sublist)):
answer.append((tail_node, inversions))
else:
for idx, val in enumerate(reversed_sublist):
add_permutations(
filter(lambda x: x != val),
ListNode(val, tail_node,
inversions + idx
)
add_permutations(reversed(sorted_list), EmptyListNode(), 0)
return answer
You might wonder at my claim of amortized O(1) work with all of this copying. That's because if m elements are left we do O(m) work then amortize it over m! elements. So the amortized cost of the higher level nodes is a converging cost per bottom call, of which we need one per permutation.