Count unique values in subarrays - algorithm

Array a*b is given, which contains numbers up to 1e5, and we have to sum the count of unique numbers in every k*k subarray,
there are a-k*b-k subarrays
e.g
1 2 3 4
3 2 4 1
for k=2
subarrays are
{1,2,3,2}(3distinct values)
{2,3,2,4}(3distinct values)
{3,4,4,1}(3distinct values)
output is 9
Is there a faster approach than using a table which stores count of every number ocurrencies in an actaully processed k*k subarray(e.g at index 3 we store count of 3's in a subarray), moving a k*k window by 1 and adding values from right and removing from left, if after incremention value is 1 - increment unique numbers counter; if after decrementation value is 0 - decrement unique numbers counter.
After getting to the end of the row, go 1 down and move in the opposite direction.
Not worried about memory usage,im just looking for a way to do this faster

a == b is an equivalence relation.
Given A the set of elements (your subarray), you can find the equivalence classes of the relation with the method you found:
For each element x in the subarray A you take c[x] which is an int (c array elements all initialized to 0). If this c[x] == 0 then you have a new unique element so c[x]++. Otherwise you increment c[x].
This algorithm is linear to the number of elements in the subarray (obviously you iterate this process for each subarray and sum the results to get what you want).
But time complexity can’t be lower, cause you need to check each element anyway.

Related

Given four arrays of equal size n, how many ways can I choose an element of each array with a sum of k?

If I had four arrays with the same size, how do I determine the number of ways to choose one element from each array such that the four elements have the same sum?
For example, there are 81 ways to choose choose an element from each array with a sum of 4.
A. 1 1 1
B. 1 1 1
C. 1 1 1
D. 1 1 1
I am not sure how to do this without some sort of brute forcing.
The idea
Number of ways to get sum k from 1 array = number of occurences of k in the array.
Number of ways to get sum k from 2 arrays = sum(count(k-x) for each element x in array 2), where count(y) is number of ways of getting sum y from the first array. If you memoize the results from point #1, getting count(y) can be done in O(1).
Number of ways to get sum k from 3 arrays = sum(count(k-x) for each element x in array 3), where count(y) is number of ways of getting sum y from the first two arrays. Again, if you memoize the results from point #2, getting count(y) can be done in O(1).
You should get the concept by now; number of ways to get sum k from n arrays = sum(count(k-x) for each element x in the nth array), where count(y) is number of ways of getting sum y from the first n-1 arrays.
Dynamic programming
You need to build a memoization table which basically tells you the number of ways of getting sum x from the first y arrays. If you have this table for the first n-1 arrays, you can calculate all sums including the n-th array efficiently and update the table.

Maximum sum of non consecutive elements (Dynamic Programming)

Given an array of positive integers, what's the most efficient
algorithm to find non-consecutive elements from this array which, when
added together, produce the maximum sum?
The dynamic programming solution is to use an auxiliary array maxSum holding the max sum up until that particular index. We start by setting the first 2 indices of the array, and fill the rest of the array with max(array[i]+maxSum[i-2], maxSum[i-1]).
I understand that we cannot add adjacent elements, but I am struggling to understand how the above solution takes into consideration that it is possible for the the previous element in maxSum[i] to not be the result of summing with array[i].
For example:
index: 0 1 2 3 4
array: 3 5 -7 8 10
maxSum: 3 5 5 _
We see that maxSum[2] is not a result of summing with array[2].
To find maxSum[3] = max(array[3]+maxSum[1], maxSum[2]), but why don't we consider maxSum[2] + array[3]? Since it is possible for maxSum[2] to not consist of the adjacent array[2] value.
how does the above solution take into consideration that it is possible for the previous element in maxSum[i] to not be the result of summing with array[i]?
Simply. If the previous element in maxSum[i] is not to be included in the result of summing with array[i], we can look at maxSum[i - 2]. We do this explicitly in
array[i]+maxSum[i-2]
we compare that against the option of not including array[i], which is
maxSum[i-1]
First all, you might not understand the procedure completely:
For each index i, maxSum represents the max of (sum by including i-th element, sum by excluding i-th element)
maxSum[3] = max(array[3]+maxSum[1], maxSum[2]), because array[3]+maxSum[1] represents the sum if array[3] is taken, and maxSum[2] if array[3] is excluded.
I am assuming you need an explanation of the reasoning, here it is.
Let M[i] be the maximum sum we can obtain by including the first i elements of the array A (with the condition that no two are consecutive). There are two possibilities:
M[i] includes element i. In this case it cannot include element i-1
so M[i]=A[i]+M[i-2]
M[i] does not include element i. In this case M[i]=M[i-1].
Since we don't know if it actually includes i or not we compute both cases and choose the maximum between the two thus
M[i]=max(M[i-1],A[i]+M[i-2])

find maximum possible min value of array

There is an array containing n integers. In each step we are allowed to increment all the elements present in any subarray of size w by 1. The maximum number of such steps allowed is m. Any element of the array cannot be incremented more than k times. We are required to maximize the minimum possible element in the array after these operations.
For example we are given n=6, m=2, w=3, k=1
And the array is 2 2 2 2 1 1.
then the answer is 2, as k=1( we can only increment each element once, hence considering a window of size 3 at the end of the array will give us the required answer. Also note that since m=2, the first 3 elements will be incremented in the next step.)
How do i approach this problem?
Edit: Constraints are
1 ≤ w ≤ n ≤ 10^5
1 ≤ k ≤ m ≤ 10^5
Elements in the array are in range 1 to 10^9.

Select pairs of numbers with the minimum overall difference

Given n pairs of numbers, select k pairs so that the difference between the minimum value and the maximum value is minimal. Note that 2 numbers in 1 pair cannot be separated. Example (n=5, k=3):
INPUT OUTPUT (return the index of the pairs)
5 4 1 2 4
1 5
9 8
1 0
2 7
In this case, choosing (5,4) (1,5) (1,0) will give a difference of 5 (max is 5, min is 0). I'm looking for an efficient way (n log n) of doing this since the input will be pretty large and I don't want to go through every possible case.
Thank you.
NOTE: No code is needed. An explanation of the solution is enough.
Here's a method with O(n log n) time complexity:
First sort the array according to the smaller number in the pair. Now iterate back from the last element in the sorted array (the pair with the highest minimum).
As we go backwards, the elements already visited will necessarily have an equal or higher minimum than the current element. Store the visited pairs in a max heap according to the maximal number in the visited pair. If the heap size is smaller than k-1, keep adding to the heap.
Once the heap size equals k-1, begin recording and comparing the best interval so far. If the heap size exceeds k-1, pop the maximal element off. The heap is guaranteed to contain the first k-1 pairs where the minimal number is greater than or equal to the current minimal number and the maximal is smallest (since we keep popping off the maximal element when the heap size exceeds k-1).
Total time O(n log n) for sorting + O(n log n) to iterate and maintain the heap = O(n log n) in total.
Example:
5 4
1 5
9 8
1 0
2 7
k = 3
Sort pairs by the smaller number in each pair:
[(1,0),(1,5),(2,7),(5,4),(9,8)]
Iterate from end to start:
i = 4; Insert (9,8) into heap
i = 3; Insert (5,4) into heap
i = 2; Range = 2-9
i = 1; Pop (9,8) from heap; Range = 1-7
i = 0; Pop (2,7) from heap; Range = 0-5
Minimal interval [0,5] (find k matching indices in O(n) time)
Lets keep to sorted arrays: one which sorted according to minimal number in pair and other to maximal. Lets iterate over first array and fix minimal number in answer. We can keep pointer on k-th number in second array. When we go to next pair we remove all pairs with less minimal value from second array and forward pointer if needed. To find position in log n time in second array we can keep additional map between pair and position.

Sorting a permutation with minimum cost

I am given a permutation of elements {1, 2, 3, ..., N} and I have to sort it using a swap operation. An operation which swaps elements x, y has cost min(x,y).
I need to find out the minimum cost of sorting the permutation. I tought about a greedy going from N to 1 and putting each element on it's position using a swap operation, but this is not a good idea.
Would this be optimal:
Find element 2
If it is not at correct place already
Find element at position 2
If swapping that with 2 puts both to right place
Swap them
Cost = Cost + min(2, other swapped element)
repeat
Find element 1
If element 1 is at position 1
Find first element that is in wrong place
If no element found
set sorted true
else
Swap found element with element 1
Cost = Cost + 1
else
Find element that should go to the position where 1 is
Swap found element with element 1
Cost = Cost + 1
until sorted is true
If seeks are trivial, then the minimum number of swaps will be determined by the number of cycles. It would follow a principle similar to Cuckoo Hashing. You take the first value in the permutation, and look at the value at the index of the value at the original index. If those match, then swap for a single operation.
[3 2 1] : Value 3 is at index one, so look at the value at index 3.
[3 2 1] : Value 1 is at index 3, so a two index cycle exists. Swap these values.
If not, push the first index onto a stack and seek the index for the value of the second index. There will eventually be a cycle. At that point, start swapping by popping values off the stack. This will take a number of swaps equal to n-1, where n is the length of the cycle.
[3 1 2] : Value 3 is at index one, so look at the value at index 3.
[3 1 2] : Value 2 is at index 3, so add 3 to the stack and seek to index 2. Also store 3 as the beginning value of the cycle.
[3 1 2] : Value 1 is at index 2, so add 2 to the stack and seek to index 1.
[3 1 2] : Value 3 is the beginning of the cycle, so swap pop 2 off the stack and swap values 1 and 2.
[1 3 2] : Pop 3 off the stack and swap 2 and 3, resulting in a sorted list with 2 swaps.
[1 2 3]
With this algorithm, the maximum number of swaps will be N-1, where N is the total number of values. This occurs when there is an N length cycle.
EDIT : This algorithm gives the minimum number of swaps, but not necessarily the minimum value using the min(x, y) function. I haven't done the math, but I believe that the only time when swap(x, y) = {swap(1, x), swap(1, y), swap(1, x)} shouldn't be used is when x in {2,3} and n < 2; Should be easy enough to write that as a special case. It may be better to check and place 2 and 3 explicitly, then follow the algorithm mentioned in the comments to achieve sorting in two operations.
EDIT 2 : Pretty sure this will catch all cases.
while ( unsorted ) {
while ( 1 != index(1) )
swap (1 , index (1) )
if (index(2) == value#(2))
swap (2, value#(2) )
else
swap (1 , highest value out of place)
}
If you have permutation of the numbers 1, 2, ..., N, then the sorted collection will be precisely 1, 2, ..., N. So you know the answer with complexity O(0) (i.e. you don't need an algorithm at all).
If you actually want to sort the range by repeated swapping, you can repeatedly "advance and cycle": Advance over the already sorted range (where a[i] == i), and then swap a[i] with a[a[i]] until you complete the cycle. Repeat until you reach the end. That needs at most N − 1 swaps, and it basically performs a cycle decomposition of the permutation.
Hmm. An interesting question. A quick algorithm that came up to my mind is to use elements as indices. We first find the index of an element that has 1 as value, and swap it with element of that number. Eventually this will end up with 1 appearing at first position, this means you have to swap 1 with some element that isn't yet in the position, and continue. This tops at 2*N-2, and has lower limit at N-1 for permutation (2,3,...,N,1), but the exact cost will vary.
Okay, given above algorithm and examples, I think the most optimal will be to follow exchanging 1 with anything until it first hits first place, then exchange 2 with second-place if it's not in place already, then continue swapping 1 with anything not yet in place, until sorted.
set sorted=false
while (!sorted) {
if (element 1 is in place) {
if (element 2 is in place) {
find any element NOT in place
if (no element found) sorted=true
else {
swap 1 with element found
cost++
}
} else {
swap 2 with element at second place
cost+=2
}
} else {
find element with number equals to position of element 1
swap 1 with element found
cost++
}
}
Use a bucket sort with bucket size of 1.
The cost is zero, since no swaps occur.
Now make a pass through the bucket array, and swap each value back to it's corresponding position in the original array.
That is N swaps.
The sum of N is N(N+1)/2 giving you an exact fixed cost.
A different interpretation is that you just store from the bucket array, back into the original array. That is no swaps, hence the cost is zero, which is a reasonable minimum.

Resources