Time complexity in terms of n if time complexity is O(x*y) where x+y = n - arrays

This code is to move all the zeroes in the vector to the end of the vector while maintaining the order of the non zero elements.
Eg: 0 3 0 8 0 9
Output : 3 8 9 0 0 0
I wrote the following code for this
void moveZeroes(vector<int>& nums) {
vector<int> v, v1; // v has the index of all the zero elements while v1 has index of non zero elements
for(int i = 0; i < nums.size(); i++){
if(nums[i] == 0)
v.push_back(i);
else v1.push_back(i);
}
//Here i'm swapping all the zero elements with non zero elements
for(int i = 0; i < v.size(); i++){
for(int j = 0; j < v1.size(); j++){
if(v[i] < v1[j]){
swap(nums[v[i]], nums[v1[j]]);
v[i] = v1[j];
}
}
}
}
So if nums has size n and v has size x & v1 has size y where x + y = n, then time complexity is O(x*y) . But what will be the time complexity in terms of n?

Let N be the the number of elements in the vector.
In the best case the time complexity would be linear, i.e, O(N). This happens in 2 cases:
when all the elements are non-zero. The second loop in which you swap elements would not be executed (v would be empty)
when all the elements are zero. In such a case only the first part of the second loop would run (v1 would be empty).
In the other cases you incur in a quadratic time complexity O(N^2) due to the double loop.
For instance, suppose that half of the elements are zero and the other half is non-zero. This means that the number of iterations would be.
N/2*N/2 = N^2/4 = O(N^2)

So if nums has size n and v has size x & v1 has size y where x + y = n, then time complexity is O(x*y) . But what will be the time complexity in terms of n?
Could be up to O(n2) if x and y are roughly n/2, e.g: y = x = n / 2 => x * y = n^2/4.
I recommend you to do the following:
void moveZeroes(vector<int>& nums)
{
for(int i = 0, p = 0; i < (int)nums.size(); ++i)
if(nums[i])
{
if(p != i)
swap(nums[i], nums[p]);
++p;
}
}
Pointer p indicates how many non zero elements have been swapped.
This way you get an O(n) time complexity, the code is clearer and don't use an extra O(n) memory consumption.

Related

Find the number of subarrays of odd lengths that have a median equal to k

Find the number of subarrays of odd lengths that have a median equal to k.
For example: array = [5,3,1,4,7,7], k=4 then there are 4 odd length subarrays with 4 as their median: [4], [1,4,7], [5,3,1,4,7], [3,1,4,7,7] therefore return 4 as the answer.
Can anyone please help me with this subarray problem, I'm not sure how to get the output.
Recently encountered this problem in Online Assessment.
However 'k' is index and 1 <= k <= n where n is length of array.
We have to find how many subarrays have arr[k] as median, also subarray has to be odd length. This is the only hint we need.
Since subarrays are odd length it can be (arr[k]) or (1 element on left and right), (2 elements on left and right), so on...
We can maintain smaller and bigger arrays of length n and populate them as follows:
if(arr[i] < arr[k])
smaller[i] = 1;
else
smaller[i] = 0;
for bigger elements than arr[k]:
if(arr[i] > arr[k])
bigger[i] = 1;
else
bigger[i] = 0;
This helps us to find in range i...j where i <= j, count of smaller and bigger elements with respect to arr[k].
For arr[k] to be median in the range [i,j], The following condition has to hold.
(smaller[j] - smaller[i - 1]) = (bigger[j] - bigger[i - 1])
In other words difference between a number of smaller and bigger elements in the range [i, j] is 0.
we create new array d of length n, such that
d[i] = smaller[i] - bigger[i]
Now problem reduces to finding the number of subarrays having a sum of 0;
But not all subarrays having sum 0 are useful to us.
We don't care about the subarrays that do not include 'k'. So,
ans = subarray_sum_zero(1, n, d) - subarray_sum_zero(1, k - 1, d) - subarray_sum_zero(k + 1, n, d)
subarray_sum_zero function finds the number of subarrays in array d.
You can find the subarray sum equals k using the map in linear time complexity.
overall runtime complexity is O(n) and space complexity is O(n).
It should be able pass the tests n = 1e5.
#adf_hater 's logic is correct ( because median is middle element so smaller elements has to be equal to number of bigger elements) . Here is the code using same logic
int sum(int start, int end, vector<int>& v) {
unordered_map<ll, ll> prevSum;
int res = 0, currSum = 0;
for (int i = start; i < end; i++) {
currSum += v[i];
if (currSum == 0)
res++;
if (prevSum.find(currSum - 0) != prevSum.end())
res += (prevSum[currSum - 0]);
prevSum[currSum]++;
}
return res ;
}
void solve(int n, vector<int>&v, int k){
vector<int>smaller(n, 0), bigger(n, 0), d(n, 0) ;
k-= 1;
for(int i = 0 ; i < n; i++)
smaller[i] = v[i] < v[k];
for(int i = 0 ; i < n; i++)
bigger[i] = v[i] > v[k] ;
for(int i = 0 ; i< n; i++)
d[i] = smaller[i] - bigger[i] ;
cout<< sum(0, n, d) - sum(0, k, d) - sum(k+1, n, d) ;
}

Time complexity finding n primes with trial division by all preceding primes

Problem : Finding n prime numbers.
#include<stdio.h>
#include<stdlib.h>
void firstnprimes(int *a, int n){
if (n < 1){
printf("INVALID");
return;
}
int i = 0, j, k; // i is the primes counter
for (j = 2; i != n; j++){ // j is a candidate number
for (k = 0; k < i; k++)
{
if (j % a[k] == 0) // a[k] is k-th prime
break;
}
if (k == i) // end-of-loop was reached
a[i++] = j; // record the i-th prime, j
}
return;
}
int main(){
int n;
scanf_s("%d",&n);
int *a = (int *)malloc(n*sizeof(int));
firstnprimes(a,n);
for (int i = 0; i < n; i++)
printf("%d\n",a[i]);
system("pause");
return 0;
}
My function's inner loop runs for i times (at the most), where i is the number of prime numbers below a given candidate number, and the outer loop runs for (nth prime number - 2) times.
How can I derive the complexity of this algorithm in Big O notation?
Thanks in advance.
In pseudocode your code is
firstnprimes(n) = a[:n] # array a's first n entries
where
i = 0
a = [j for j in [2..]
if is_empty( [j for p in a[:i] if (j%p == 0)] )
&& (++i) ]
(assuming the short-circuiting is_empty which returns false as soon as the list is discovered to be non-empty).
What it does is testing each candidate number from 2 and up by all its preceding primes.
Melissa O'Neill analyzes this algorithm in her widely known JFP article and derives its complexity as O( n^2 ).
Basically, each of the n primes that are produced is paired up with (is tested by) all the primes preceding it (i.e. k-1 primes, for the k th prime) and the sum of the arithmetic progression 0...(n-1) is (n-1)n/2 which is O( n^2 ); and she shows that composites do not contribute any term which is more significant than that to the overall sum, as there are O(n log n) composites on the way to n th prime but the is_empty calculation fails early for them.
Here's how it goes: with m = n log n, there will be m/2 evens, for each of which the is_empty calculation takes just 1 step; m/3 multiples of 3 with 2 steps; m/5 with 3 steps; etc.
So the total contribution of the composites, overestimated by not dealing with the multiplicities (basically, counting 15 twice, as a multiple of both 3 and 5, etc.), is:
SUM{i = 1, ..., n} (i m / p_i) // p_i is the i-th prime
= m SUM{i = 1, ..., n} (i / p_i)
= n log(n) SUM{i = 1, ..., n} (i / p_i)
< n log(n) (n / log(n)) // for n > 14,000
= n^2
The inequality can be tested at Wolfram Alpha cloud sandbox as Sum[ i/Prime[i], {i, 14000}] Log[14000.0] / 14000.0 (which is 0.99921, and diminishing for bigger n, tested up to n = 2,000,000 where it's 0.963554).
The prime number theorem states that asymptotically, the number of primes less than n is equal to n/log n. Therefore, your inner loop will run Theta of i * max =n / log n * n times (assuming max=n).
Also, your outer loop runs on the order of n log n times, making the total complexity Theta of n / log n * n * n log n = n^3. In other words, this is not the most efficient algorithm.
Note that there are better approximations around (e.g. the n-th prime number is closer to:
n log n + n log log n - n + n log log n / log n + ...
But, since you are concerned with just big O, this approximation is good enough.
Also, there are much better algorithms for doing what you're looking to do. Look up the topic of pseudoprimes, for more information.

Can someone explain this "kth smallest integer in an unsorted array" code? - C

I basically have to write a function that takes in an array, an int n that indicates elements in array and int k which is the kth smallest int in the array (not kth smallest position). The array is not allowed to be modified (sorted). I've spent a while trying to get my head around this solution but I keep confusing myself.
Can someone try and explain it to me? Thanks!
int
kth_smallest(int A[], int n, int k) {
int i, j;
int smaller, equal;
for (i = 0; i < n; i++) {
smaller = 0;
equal = 0;
for (j = 0; j < n; j++) {
smaller += (A[j] < A[i]);
equal += (A[j] == A[i]);
}
if (smaller <= k && k < smaller + equal) {
return A[i];
}
}
printf("No %d'th smallest possible in array of %d items\n", k, n);
exit(EXIT_FAILURE);
}
Here is the step out solution that I calculated for some test data.
A[4] = {1,1,4,3} | n = 4 | k = 3 | Expected outcome = 4
Loop 1 (A[i] = 1) :
smaller = 0.
equal = 2.
test: smaller <= k && k < smaller+equal | 0 <= 3 && 3 < 2 | FALSE
Loop 2 (A[i] = 1):
smaller = 0.
equal = 2.
test: smaller <= k && k < smaller+equal | 0 <= 3 && 3 < 2 | FALSE
Loop 3 (A[i] = 4):
smaller = 3.
equal = 1.
test: smaller <= k && k < smaller+equal | 3 <= 3 && 3 < 4 | TRUE
RETURN A[i] (=4). (Which matches expected)
Third smallest int in A is 4, with 1 and 3 before it.
Tip: In understanding such algorithms it's often helpful to consider the basic (and corner) cases first. Start by assuming all elements in the array are distinct. Then by the time you get to the 'if' clause, 'smaller' = num of elements smaller than current inspected element (A[i]) and 'equal' = 1. So the 'if' clause becomes:
if (smaller <= k && k < smaller + 1)
which necessarily means
smaller = k
so by returning A[i] you are returning the element that has (k-1) smaller elements in the array (because 'k' is a 0-based index), i.e. the k-th smallest element, as expected. Now look at an example where all elements are equal. smaller = 0 and equal = n (always). so any 'k' in the range 0..n-1 will return the single number in the array, again, as expected. Now consider your example again and see if you can make better sense of it. Good luck!

Three elements in array whose xor is maximum

I want to know a algorithm to find out the maximum xor value of three elements of an array.
I have read about the maximum xor for two elements from an array but cannot understand how to apply it on finding the maximum value of XOR taking 3 elements of an array . Can someone point out a hint ?
Required complexity : less than O(N^3) where N is the number of elements in the array.
Example:
A = [1,2,3,4]
All Possible Triplets :-
1^2^3 = 0
1^2^4 = 7
1^3^4 = 6
2^3^4 = 5
Thus, the maximum XOR value is 7.
Edit :
I have thought of a solution having complexity O(N^2 * log(MAX)) and it has solved my purpose :D .
MAX = Maximum Value in the Array
Well, I have found a solution with complexity O(N^2 * log(MAX)) where MAX is the largest value in the array .
Let there be 3 elements X,Y,Z fron the array A.
where X = A[i] , Y = A[j] , Z = A[k] and i != j != k
We want the maximum value of (X^Y^Z) .
Let us assume W = X*Y.
Then we would like to find such a Z which give maximum value for W^Z and Z != X and Z != Y
Now this has been reduced to the problem of finding "Two elements whose XOR is maximum" which can be done for a given W in O(log(MAX)) using a Trie .
Explanation for Trie :
Let us assume W = 10001 here W is in binary .
Now we know 1^0 = 1 , 0^0 = 0 , 1^1 = 0 , so the maximum value we
can get for W^Z is when Z is 01110 because
W^Z will give = 11111.
But it is not necessary to have 15 or Base2(11111) in our array so
we would take the best possible option available.
So we will create a Trie of all the elements of the array
according to their binary representation.
If A = [1,2,7] , then 1 = 001 , 2 = 010 , 7 = 111 in
binary .
Then the Trie will look like :-
Top
/ \
0 1
/ \ \
0 1 1
\ / \
1 0 1
Now to lets assume W = 7 , and we want to find Z such that
W^Z is maximum (when Z = 000 ) then we will start at the Top and look if we have branch leading to 0 since the first bit of 7 is 1
, then we will down through that branch and then again look if we have
branch leading to 0 at 2nd bit , again we find it , then for the last
time we search for branch leading to a 0 at 3rd bit but we do not find
it , so we go down through the other branch which gives us Z =
001. Thus, the maximum W^Z will be 7^1 = 6 . Now , the
complexity of finding Z will be maximum height of the Trie which
will be log(MAX).
Thus , we have N*(N-1)/2 number of W's and for each W we can find the Maximum value of W^Z and if we take the Maximum from all the values of W^Z we will have our answer.
With three nested loop:
int max2=0,max3=0;
for (int i=0;i<arr.size();i++)
for (int j=0;j<arr.size();j++)
for (int k=0;k<arr.size();k++)
{
if (arr[i]^arr[j]>max2) // for 2 elements
max2 = arr[i]^arr[j];
if (arr[i]^arr[j]^arr[k]>max3) // for 3 elements
max3 = arr[i]^arr[j]^arr[k];
}
int max = max2; // for both
if (max3>max2)
max = max3;
following will do the O(N^3), but in an more optimized approach - not testing same combination more than once, not testing element against itself,
and somewhat optimized evaluation (xoring the first two elements once for all possible third elements)
Number of Xor operations performed will be:
n(n-1)(n-2)/6 + n(n-1)/2
Complexity is still n(n-1)(n-2)/6 ===> O(N^3) though.
unsigned int maxXor3(unsigned int* element, int len)
{
unsigned int max = 0;
unsigned int xor2 = 0;
unsigned int xor3 = 0;
int j = k = 0;
for (int i = 0 ; i < len ; i++)
{
for (j = i + 1 ; j < len ; j++)
{
xor2 = element[i] ^ element[j];
for(k = j + 1; k < len; k++)
{
xor3 = xor2 ^ element[k];
if (xor3 > max)
max = xor3;
}
}
}
return max;
}

Algorithm for linear equations with more solutions

Can someone help me out with algorithm for solving linear equations in modular arithmetic (!). I need only the "smallest" solution. Smallest means lexicographically first.
Let's have this system:
3x1+2x2=3
4x1+3x2+1x3+2x4=4
Number next to x is index.
Matrix for this system where we use modulo 5 (0<=x<=p where p is our modulo) is
3 2 0 0 0 | 3
4 3 1 2 0 | 4
The smallest solution for this is (0,4,0,1,0). I have to write an algorithm which will give me that solution.
I was thinking about brute-force, because p<1000. But I dont how to do it, because in this situation in first row I have to x1=0 ... p-1 , then solve x2, in the second row i have to pick x3= 0 ... p-1. And solve x4. I have to do this until that system of equations hold. If I go from 0 .. p-1, then the first solution I get will be the smallest one.
PS:There can a lot of forms of matrix, like:
3 2 4 0 0 | 3
4 3 1 2 1 | 4
1 2 0 0 0 | 3
3 0 3 0 0 | 3
4 3 1 2 3 | 4
etc.
Sorry for my english, I am from asia.
Edit: I was thinking about how to determine which variables are parameters. But can't figure it out....
Ah well, what the heck, why not, here you go
#include <stdio.h>
#define L 2
#define N 5
#define MOD 5
static int M[L][N] =
{ { 3, 2, 0, 0, 0 }
, { 4, 3, 1, 2, 0 }
};
static int S[L] =
{ 3, 4
};
static void init(int * s)
{
int i;
for (i = 0; i < N; i++)
{
s[i] = 0;
}
}
static int next(int * s)
{
int i, c;
c = 1;
for (i = N-1; i >= 0 && c > 0; i--)
if ( (++s[i]) == MOD)
{
s[i] = 0;
}
else
{
c = 0;
}
return c == 0;
}
static int is_solution(int * s)
{
int i, j, sum;
for (i = 0; i < L; i++)
{
sum = 0;
for (j = 0; j < N; j++)
{
sum += M[i][j]*s[j];
}
if (sum % MOD != S[i])
{
return 0;
}
}
return 1;
}
int main(void)
{
int s[N];
init(s);
do
{
if (is_solution(s))
{
int i;
for (i = 0; i < N; i++)
{
printf(" %d", s[i]);
}
printf("\n");
break;
}
} while (next(s));
return 0;
}
You can treat this as a problem in linear algebra and Gaussian elimination mod p.
You are trying to find solutions of Mx = y mod p. Start with a square M by adding rows of 0'x = 0 if necessary. Now use Gaussian elimination mod p to reduce M, as far as possible, to upper triangular form. You end up with a system of equations such as
ax + by + cz = H
dy + ez = G
but with some zeros on the diagonal, either because you have run out of equations, or because all of the equations have zero at a particular column. If you have something that says 0z = 1 or similar there is no solution. If not you can work out one of possibly many solutions by solving from the bottom up as usual, and putting in z=0 if there is no equation left that has a non-zero coefficient for z on the diagonal.
I think that this will produce the lexicographically smallest answer if the most significant unknown corresponds to the bottom of the vector. The following shows how you can take an arbitrary solution and make it lexicographically smallest, and I think that you will find that it would not modify solutions produced as above.
Now look at http://en.wikipedia.org/wiki/Kernel_%28matrix%29. There is a linear space of vectors n such that Mn = 0, and all the solutions of the equation are of the form x + n, where n is a vector in this space - the null space - and x is a particular solution, such as the one you have worked out.
You can work out a basis for the null space by finding solutions of Mn = 0 much as you found x. Find a column where there is no non-zero entry on the diagonal, go to the row where the diagonal for that column should be, set the unknown for that column to 1, and move up the matrix from there, choosing the other unknowns so that you have a solution of Mn = 0.
Notice that all of the vectors you get from this have 1 at some position in that vector, 0s below that vector, and possibly non-zero entries above. This means that if you add multiples of them to a solution, starting with the vector which has 1 furthest down, later vectors will never disturb components of the solution where you have previously added in vectors with 1 low down, because later vectors always have zero there.
So if you want to find the lexicographically smallest solution you can arrange things so that you use the basis for the null space with the lexicographically largest entries first. Start with an arbitrary solution and add in null space vectors as best you can, in lexicographical order, to reduce the solution vector. You should end up with the lexicographically smallest solution vector - any solution can be produced from any other solution by adding in a combination of basis vectors from the null space, and you can see from the above procedure that it produces the lexicographically smallest such result - at each stage the most significant components have been made as small as possible and any alternatives must be lexicographically greater.

Resources