sum values in a range of indices with O(1) complexity [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
We are given a integer vector(V[]) and two index values, A and B. We need to sum all the integers between V[A] and V[B].
For example,
V[] == {0, 1, 2, 0, 4, 0, 3}, A == 2, B == 6
Sum == V[3] + V[4] + V[5] == 4
Is it possible to solve with O(1) complexity?
I thought about using memory address operations, but I'm still not sure how it would work(something like: sum the next (B-A) addresses values from &V[A])

If preprocessing is allowed, this can be done with a secondary array.
Each element of the second array would contain the sum of the corresponding element and all preceeding elements. This one-time preprocessing is O(n) time and O(n) space.
For example:
int Vsum[7];
Vsum[0] = V[0];
for (int i=1; i<7; i++) {
Vsum[i] = Vsum[i-1] + V[i];
}
So with your given array, the corresponding summation array Vsum would contain:
{0, 1, 3, 3, 7, 7, 10}
Once you have this, you only need to perform 2 lookups: one for the upper bound and one for the lower bound. So after preprocessing, getting the range sum is O(1) every time it is performed.
For the example of A==2 and B==6, you would then calculate Vsum[B-1] - Vsum[A] == 7 - 3 == 4

O(1) Space: no problem. But O(n) time will always be required for "random" numbers.

Related

Range updation of values in c++ vectors [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Given a vector of integers v, whose size is n and stores all 0's initially. If I want to update some elements of a range, say from index l to r, where (0<=l<r<n). Is there any efficient way instead of running loop from l to r?
For example,
v = {0,0,0,0,0,0,0}.
I want to update elements from l=2 to r=5.
Update refers to v[i] += k, where k is some known value. If k=1, then final updated vector in above case would be-
v = {0,0,1,1,1,1,0}.
Thanks:)
You can use for_each (ccpreference.com) or for_each_n
std::vector<int> data{0, 0, 0, 0, 0, 0, 0, 0};
std::for_each(data.begin() + 2, data.begin() + 6, [](int& i) { i += 1;});
// or with for_each_n
// std::for_each_n(data.begin() + 2, 4, [](int& i) { i += 1;});
for (const auto i : data) {
std::cout << i << ' ';
}
But as the comment above mentioned there will be a for loop in there, even though you don't explicitly write one.
Here a short explanation what the code does:
From the reference page we learn:
Applies the given function object f to the result of dereferencing every iterator in the range [first, last), in order.
In our case we provide for first data.begin() + 2 which is the 3rd element of the vector and for last we provide data.begin() + 6. This element is not included in the application of the function (this is what [first, last) means).
The last part is the function f that we have to provide. Here we use a lambda function that simply increases the parameter by 1. It's important that the function paramter of the lambda takes a reference (int& i) and not just a copy, otherwise the vector remain the same as we only change copies of the elements.

What is the median value is decimal? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm writing a program to find the median of an array in CPP. I am not sure if I have a clear idea about what a median is. As far as I know, I've written my program to find median but when the array is even-numbered, I'm confused whether I should print the ceiling or ground value of division ofthe decimal output I get when I divide the middle two elements from the array.
using namespace std;
void findMedian(int sortedArray[], int N);
int main()
{
int ip[4] = {1, 2, 5, 8};
findMedian(ip, 4);
}
void findMedian(int sortedArray[], int N)
{
int size = N;
int median;
if ((size % 2) != 0)
{
median = sortedArray[(size / 2)];
}
else
{
median = (sortedArray[(size / 2) - 1] + sortedArray[size / 2]) / 2;
}
cout << median;
}
Thanks in advance, also if anyone can give the literal purpose of finding a median, I'd appreciate and it'd help me not ask this question again when I have to deal with Median.
Pardon my English.
on odd array the median is unique, but in a even array there are two medians: the lower median (the one in (n/2)th position) and the upper median (the one in (n/2+1) th position). I usually always see that the lower median is used as "median" for even arrays.
In this case you need only one formula for even and odd arrays:
medianPosition = n/2; // integer division
median = sortedArray[medianPosition];
Note that it is true only for array where indices starts with zero (like C/C++).

Number of swaps in a permutation [duplicate]

This question already has answers here:
Counting the adjacent swaps required to convert one permutation into another
(6 answers)
Closed 8 years ago.
Is there an efficient algorithm (efficient in terms of big O notation) to find number of swaps to convert a permutation P into identity permutation I? The swaps do not need to be on adjacent elements, but on any elements.
So for example:
I = {0, 1, 2, 3, 4, 5}, number of swaps is 0
P = {0, 1, 5, 3, 4, 2}, number of swaps is 1 (2 and 5)
P = {4, 1, 3, 5, 0, 2}, number of swaps is 3 (2 with 5, 3 with 5, 4 with 0)
One idea is to write an algorithm like this:
int count = 0;
for(int i = 0; i < n; ++ i) {
for(; P[i] != i; ++ count) { // could be permuted multiple times
std::swap(P[P[i]], P[i]);
// look where the number at hand should be
}
}
But it is not very clear to me whether that is actually guaranteed to terminate or whether it finds a correct number of swaps. It works on the examples above. I tried generating all permutation on 5 and on 12 numbers and it always terminates on those.
This problem arises in numerical linear algebra. Some matrix decompositions use pivoting, which effectively swaps row with the greatest value for the next row to be manipulated, in order to avoid division by small numbers and improve numerical stability. Some decompositions, such as the LU decomposition can be later used to calculate matrix determinant, but the sign of the determinant of the decomposition is opposite to that of the original matrix, if the number of permutations is odd.
EDIT: I agree that this question is similar to Counting the adjacent swaps required to convert one permutation into another. But I would argue that this question is more fundamental. Converting permutation from one to another can be converted to this problem by inverting the target permutation in O(n), composing the permutations in O(n) and then finding the number of swaps from there to identity. Solving this question by explicitly representing identity as another permutation seems suboptimal. Also, the other question had, until yesterday, four answers where only a single one (by |\/|ad) was seemingly useful, but the description of the method seemed vague. Now user lizusek provided answer to my question there. I don't agree with closing this question as duplicate.
EDIT2: The proposed algorithm actually seems to be rather optimal, as pointed out in a comment by user rcgldr, see my answer to Counting the adjacent swaps required to convert one permutation into another.
I believe the key is to think of the permutation in terms of the cycle decomposition.
This expresses any permutation as a product of disjoint cycles.
Key facts are:
Swapping elements in two disjoint cycles produces one longer cycle
Swapping elements in the same cycle produces one fewer cycle
The number of permutations needed is n-c where c is the number of cycles in the decomposition
Your algorithm always swaps elements in the same cycle so will correctly count the number of swaps needed.
If desired, you can also do this in O(n) by computing the cycle decomposition and returning n minus the number of cycles found.
Computing the cycle decomposition can be done in O(n) by starting at the first node and following the permutation until you reach the start again. Mark all visited nodes, then start again at the next unvisited node.
I believe the following are true:
If S(x[0], ..., x[n-1]) is the minimum number of swaps needed to convert x to {0, 1, ..., n - 1}, then:
If x[n - 1] == n - 1, then S(x) == S(x[0],...,x[n-2]) (ie, cut off the last element)
If x[-1] != n - 1, then S(x) == S(x[0], ..., x[n-1], ..., x[i], ... x[n-2]) + 1, where x[i] == n - 1.
S({}) = 0.
This suggests a straightforward algorithm for computing S(x) that runs in O(n) time:
int num_swaps(int[] x, int n) {
if (n == 0) {
return 0;
} else if (x[n - 1] == n - 1) {
return num_swaps(x, n - 1);
} else {
int* i = std::find(x, x + n, n - 1);
std::swap(*i, x[n - 1])
return num_swaps(x, n - 1) + 1;
}
}

Maximum subarray_problem understanding [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am researching the maximum subarray problem. It would appear that I haven't gotten the core idea. Let's say you have the following array: int arr[] ={10, 4, 2, 12, 16, 1} From what I understand the maximum subarray should be equal to 14, since the lowest and highest possible sub array is 2 (the third element) and 16 (the 5th element) right? Well, apperantly not. I implemented the linear time algorithm which I found here: http://heliang.me/wiki/index.php?title=4.1_The_maximum-subarray_problem
It's implementation in c++"
int max_sarr(int arr[], int size)
{
int max_sum = -9999;
int sum = 0;
for(int i = 0; i < size; i++)
{
sum += arr[i];
if(sum > max_sum)
max_sum = sum;
if(sum < 0)
sum = 0;
}
return sum;
}
int main()
{
int arr[] = {10, 4, 2, 12, 16, 1};
int p = max_sarr(arr, 6);
cout << p << endl;
return 0;
}
The output is 45. So... where is the mistake in my thought process ?
You misunderstand the problem. The problem is to find the contiguous subarray of the given array such that it has the highest sum of all subarrays. That is, it basically finds a first element and last element within the array which, if you summed up the elements including and between them, would give you the maximum possible value.
If all of the values in your array are positive, then the maximum subarray is always the entire array. In this case, if you add up all the elements in the array, you get 45.
Consider an array with values {-5, 10, -3, 22}. We can enumerate all of the subarrays of this:
Subarrays of length 0: {}
Subarrays of length 1: {-5} {10} {-3} {22}
Subarrays of length 2: {-5, 10} {10, -3} {-3, 22}
Subarrays of length 3: {-5, 10, -3} {10, -3, 22}
Subarrays of length 4: {-5, 10, -3, 22}
The subarray with the maximum sum is {10 -3 22}, whose sum is 29.
sftrabbit's answer is great, however I strongly recommend the The Maximum Subarray Problem section in CLRS book page 68. It is very clear and it also discusses the asymptotic complexity and the real life occurences of the problem.
In addition to this, as you might expect, an array with all positive elements, the maximum subarray of it will be the array itself.

Making a long vector(coloumn Matrix) using small arrays [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm trying to make one vector(feature vector) which contains array elements.
Suppose I have an array arr1 of size nx1 in first iteration. I have to add this array elements to the CvMat matrix featureVect of size, 2*n x 1.
In next iteration I have an array arr2 of size nx1, and now I have to add this array to featureVect from row n+1 to 2*n (using a one-based index)
Suppose I have
int arr1[4] = {1, 2, 3, 4};
int arr2[4] = {5, 6, 7, 8};
CvMat *featureVect;
Now I want the result to look like this (where featureVect is a one column matrix)
featureVect = {1, 2, 3, 4, 5, 6, 7, 8};// featureVect size is 8x1;
If you're using C++ with OpenCV I would recommend the Mat class. Then,
Mat featureVect(8,1,CV_32S); //CV_32s <=> int (32-bit signed integer)
const int n = 4;
for(int i = 0; i < n; ++i)
{
featureVect.at<int>(i,0) = arr1[i];
featureVect.at<int>(i+n,0) = arr2[i];
}