Efficient way to find sub-array dividing by n - algorithm

I have an N-size array A, that contain natural numbers.
I need to find an efficient algorithm that finding a pair of indexes, so that the sum of the sub-array elements A[i..j], is divided by N without a reminder of devision.
Any ideas?

The key observation is:
sum(A[i..j]) = sum(A[1..j]) − sum(A[1..(i−1)])
so N divides sum(A[i..j]) if and only if sum(A[1..(i−1)]) and sum(A[1..j]) are congruent modulo N
that is, if sum(A[1..(i−1)]) and sum(A[1..j]) have same remainder when you divide both by N.
So if you just iterate over the array tallying the "sum so far", and keep track of the remainders you've already seen and the indexes where you saw them, then you can do this in O(N) time and O(N) extra space.

Related

count the number of subarrays in a given array with its average being k

Given an integer array a, and an integer k, we want to design an algorithm to count the number of subarrays with the average of that subarray being k. The most naive method is to traverse all possible subarrays and calculate the corresponding average. The time complexity of this naive method is O(n^2) where $n$ is the length of a. I wonder whether it is possible to do better than O(n^2).
Usually for this kind of problem, one uses prefix sum together with a hashmap, but this technique does not seem to apply here.
Consider a prefix sum array, call it a.
You want to find all such pairs (i, j) that (a[j]-a[i])/(j-i) == k.
Now watch the hands:
(a[j]-a[i])/(j-i) == k
a[j]-a[i] == k*(j-i)
a[j]-a[i] == k*j-k*i
a[j]-k*j == a[i]-k*i
So if you subtract k*j from jth element of the prefix sum array, you are left with the task of counting identical pairs.

N integers to be sorted in O(n)?

Assume you have n integers in the range (0, n2
). These integers are all square roots of other integers.
Indicate whether it is possible to sort these numbers in O(n) or not
I assume we would take square roots of each of the integers but im not sure if its possible to sort them in O(n) any help would be appreciated
Yes, if you are willing to use O(n) space:
You have stored your N integers in array A.
Allocate a bitmap B with 2n+1 bits, initializated at zero.
For each integer, set B[A[i]] = 1
Create an empty list:
Iterate B in order, so that if B[i] == 1 then i is added to the list.
It can be done in time O(2n) == O(n).

Maximum number of permutations

Some sorting algorithms, like Insertion Sort, have a Θ(n) asymptotic runtime for some subset of the n! possible permutations of n elements, which means that for those permutations, the number of comparisons that Insertion Sort does is kn for some constant k. For a given constant k, what is the maximum number of permutations for which any given comparison sort could terminate within kn comparisons?
Number of operations in insertion sort depends on the number of inversions. So we need to evaluate number of permutations of n values (1..n for simplicity), containing exactly k inversions.
We can see that Inv(n, 0) = 1 - sorted array
Also Inv(0, k) = 0 - empty array
We can get array with n elements and k inversions:
-adding value n to the end of array with n-1 items and k inversions (so number of inversions remains the same)
-inserting value n before the end of array with n-1 items and k-1 inversions (so adding one inversion)
-inserting value n before two elements in the end of array with n-1 items and k-2 inversions (so adding two inversions)
-and so on
Using this approach, we can just fill a table Inv[n][k] row-by-row and cell-by-cell
Inv[n][k] = Sum(Inv[n-1][i]) where j=0..k
Every comparison at most doubles the never of input permutations you can distinguish. Thus, with kn comparisons you can sort at most 2^(kn) permutations.

Finding the kth smallest element in a sequence where duplicates are compressed?

I've been asked to write a program to find the kth order statistic of a data set consisting of character and their occurrences. For example, I have a data set consisting of
B,A,C,A,B,C,A,D
Here I have A with 3 occurrences, B with 2 occurrences C with 2 occurrences and D with on occurrence. They can be grouped in pairs (characters, number of occurrences), so, for example, we could represent the above sequence as
(A,3), (B,2), (C,2) and (D,1).
Assuming than k is the number of these pairs, I am asked to find the kth of the data set in O(n) where n is the number of pairs.
I thought could sort the element based their number of occurrence and find their kth smallest elements, but that won't work in the time bounds. Can I please have some help on the algorithm for this problem?
Assuming that you have access to a linear-time selection algorithm, here's a simple divide-and-conquer algorithm for solving the problem. I'm going to let k denote the total number of pairs and m be the index you're looking for.
If there's just one pair, return the key in that pair.
Otherwise:
Using a linear-time selection algorithm, find the median element. Let medFreq be its frequency.
Sum up the frequencies of the elements less than the median. Call this less. Note that the number of elements less than or equal to the median is less + medFreq.
If less < m < less + medFreq, return the key in the median element.
Otherwise, if m ≤ less, recursively search for the mth element in the first half of the array.
Otherwise (m > less + medFreq), recursively search for the (m - less - medFreq)th element in the second half of the array.
The key insight here is that each iteration of this algorithm tosses out half of the pairs, so each recursive call is on an array half as large as the original array. This gives us the following recurrence relation:
T(k) = T(k / 2) + O(k)
Using the Master Theorem, this solves to O(k).

Finding sub-array sum in an integer array

Given an array of N positive integers. It can have n*(n+1)/2 sub-arrays including single element sub-arrays. Each sub-array has a sum S. Find S's for all sub-arrays is obviously O(n^2) as number of sub-arrays are O(n^2). Many sums S's may be repeated also. Is there any way to find count of all distinct sum (not the exact values of sums but only count) in O(n logn).
I tried an approach but stuck on the way. I iterated the array from index 1 to n.
Say a[i] is the given array. For each index i, a[i] will add to all the sums in which a[i-1] is involved and will include itself also as individual element. But duplicate will emerge if among sums in which a[i-1] is involved, the difference of two sums is a[i]. I mean that, say sums Sp and Sq end up at a[i-1] and difference of both is a[i]. Then Sp + a[i] equals Sq, giving Sq as a duplicate.
Say C[i] is count of the distinct sums in which end up at a[i].
So C[i] = C[i-1] + 1 - numbers of pairs of sums in which a[i-1] is involved whose difference is a[i].
But problem is to find the part of number of pairs in O(log n). Please give me some hint about this or if I am on wrong way and completely different approach is required problem point that out.
When S is not too large, we can count the distinct sums with one (fast) polynomial multiplication. When S is larger, N is hopefully small enough to use a quadratic algorithm.
Let x_1, x_2, ..., x_n be the array elements. Let y_0 = 0 and y_i = x_1 + x_2 + ... + x_i. Let P(z) = z^{y_0} + z^{y_1} + ... + z^{y_n}. Compute the product of polynomials P(z) * P(z^{-1}); the coefficient of z^k with k > 0 is nonzero if and only if k is a sub-array sum, so we just have to read off the number of nonzero coefficients of positive powers. The powers of z, moreover, range from -S to S, so the multiplication takes time on the order of S log S.
You can look at the sub-arrays as a kind of tree. In the sense that subarray [0,3] can be divided to [0,1] and [2,3].
So build up a tree, where nodes are defined by length of the subarray and it's staring offset in the original array, and whenever you compute a subarray, store the result in this tree.
When computing a sub-array, you can check this tree for existing pre-computed values.
Also, when dividing, parts of the array can be computed on different CPU cores, if that matters.
This solution assumes that you don't need all values at once, rather ad-hoc.
For the former, there could be some smarter solution.
Also, I assume that we're talking about counts of elements in 10000's and more. Otherwise, such work is a nice excercise but has not much of a practical value.

Resources