I find difficult to find the inversion pairs in the array. I got the number of inversion pairs in the array but the logic seems so complex that I can't able to list pairs. I am new to C++, any help is appreciated.
Example:
Input: arr[] = {8, 4, 2, 1}
Output: 6
Expecting this output
Given array has six inversions (8,4) and index(0,1), (4,2) and index(1,2),
(8,2) and index(0,2), (8,1) and index(0,3), (4,1) and index(1,3), (2,1) and index(2,4)
// C++ program to count inversions using Binary Indexed Tree
#include<bits/stdc++.h>
using namespace std;
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[].
int getSum(int BITree[], int index)
{
int sum = 0; // Initialize result
// Traverse ancestors of BITree[index]
while (index > 0)
{
// Add current element of BITree to sum
sum += BITree[index];
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, int val)
{
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
BITree[index] += val;
// Update index to that of parent in update View
index += index & (-index);
}
}
// Returns inversion count arr[0..n-1]
int getInvCount(int arr[], int n)
{
int invcount = 0; // Initialize result
// Find maximum element in arr[]
int maxElement = 0;
for (int i=0; i<n; i++)
if (maxElement < arr[i])
maxElement = arr[i];
// Create a BIT with size equal to maxElement+1 (Extra
// one is used so that elements can be directly be
// used as index)
int BIT[maxElement+1];
for (int i=1; i<=maxElement; i++)
BIT[i] = 0;
// Traverse all elements from right.
for (int i=n-1; i>=0; i--)
{
// Get count of elements smaller than arr[i]
invcount += getSum(BIT, arr[i]-1);
// Add current element to BIT
updateBIT(BIT, maxElement, arr[i], 1);
}
return invcount;
}
// Driver program
int main()
{
int arr[] = {8, 4, 2, 1};
int n = sizeof(arr)/sizeof(int);
cout << "Number of inversions are : " << getInvCount(arr,n);
return 0;
}
The program creates new array BITree[] that makes it more complex. How the position of the element is found.
Related
PROBLEM: Given an array arr[] of size N and an integer K. Find the maximum for each and every contiguous subarray of size K.
Why doesn't the following test case pass for the code below:-
Input: 5 4 1 2 3 4 5 Its Correct output is:
4 5
And my Code's output is: 4 5 5
int find_max(queue<int> q){
int max = 0;
while (!q.empty())
{
if (q.front() > max)
max = q.front();
q.pop();
}
return max;
}
vector<int> max_of_subarrays(int *arr, int n, int k){
// your code here
vector<int> res;
queue<int> q;
vector<int> temp;
int i = 0, j = 0;
//for cases where n = k
if(k == n){
sort(arr, arr+n);
temp.push_back(arr[n-1]);
return temp;
}
while(j < n)
{
q.push(arr[j]);
if ((j - i + 1) < k)
{
j++;
}
else if((j - i + 1) == k)
{
int x = find_max(q);
res.push_back(x);
//removing first entered element from queue
q.pop();
//pushing the next element to the queue
q.push(arr[i]);
i++;
j++;
}
}
//for last window
int x = find_max(q);
res.push_back(x);
return res;
}
Can someone tell what's going wrong here?
Yes, we can help.
The line q.push(arr[i]); is wrong. Index i will not be the last element. So, rather index j+1 should be used. But this will be pushed anyway in the next loop run.
So, you do not need this line at all. Delete it!
And in your while loop, you find already all results. So, you can simply delete the last 2 lines
int x = find_max(q);
res.push_back(x);
Then your function will work.
But for real C++ it is too complicated.
You could also use the following approach with a `````std::deque````:
auto maxOfContiguousSubArray(std::vector<int>& data, size_t subArraySize) {
// Here we will store the result
std::vector<int> result{};
// And this will hold our subarray. We use a deque, because we will have then have required iterators
std::deque<int> subArray{};
// Special case: Number of elements is less or equal the subarray size
if (data.size() <= subArraySize) {
// Get the one max element
result.push_back(*std::max_element(data.begin(), data.end()));
}
// Go over all numbers in data
else for (size_t index{}; index < data.size(); index++) {
// Store value in sub array
subArray.push_back(data[index]);
// If there are enough values in subarray, then
if (index >= subArraySize-1 ) {
// Get the max value
result.push_back(*std::max_element(subArray.begin(), subArray.end()));
// Remove the first value
subArray.pop_front();
}
}
return result;
}
int main() {
size_t n{}, k{};
// Read number of elements and size of subarray
if (std::cin >> n >> k) {
// Here we will store our numbers
std::vector<int> data{};
// copy n numbers from std::cin into data
std::copy_n(std::istream_iterator<int>(std::cin), n, std::back_inserter(data));
// Calculate the max values
auto max = maxOfContiguousSubArray2(data, k);
// Show the user output
std::copy(max.begin(), max.end(), std::ostream_iterator<int>(std::cout, " "));
}
return 0;
}
But basically, you do not need a subarray at all. You can simply build a sliding door with iterators or with indices.
Then the function would look like that:
auto maxOfContiguousSubArray2(std::vector<int>& data, size_t subArraySize) {
// Here we will store the result
std::vector<int> result{};
// Special case: Number of elements is less or equal the subarray size
subArraySize = std::min(data.size(), subArraySize);
// Find the max element of the window
for (auto first{ data.begin() }, last{ data.begin() + subArraySize-1 }; last != data.end(); ++first, ++last)
result.push_back(*std::max_element(first, last));
return result;
}
Problem - Given an array arr[] of size N and an integer K. Find the maximum for each and every contiguous subarray of size K.
This is how "Maximum of all subarrays of size k" problem is implemented in Java
class Solution
{
static ArrayList <Integer> max_of_subarrays(int arr[], int n, int k)
{
int i = 0,j = 0;
ArrayList <Integer> ans = new ArrayList <Integer>();
Deque<Integer> q = new LinkedList<Integer>();
while(j<n){
while(q.isEmpty() == false && q.peekLast() < arr[j])
q.removeLast();
q.addLast(arr[j]);
if(j-i+1 < k)
j++;
else if(j-i+1 == k){
ans.add(q.peekFirst());
if(arr[i] == q.peekFirst())
q.removeFirst();
i++;
j++;
}
}
return ans;
}
}
this is the code given in the editorial to print the possible combinations print all possible combinations of r elements in a given array of size n.I am asking about the for loop used inside the combinationuntil() function.what is the condition used inside the for loop i cannot understand.
#include<bits/stdc++.h>
using namespace std;
void combinationUtil(int arr[], int data[],
int start, int end,
int index, int r);
// The main function that prints
// all combinations of size r
// in arr[] of size n. This function
// mainly uses combinationUtil()
void printCombination(int arr[], int n, int r)
{
// A temporary array to store
// all combination one by one
int data[r];
// Print all combination using
// temprary array 'data[]'
combinationUtil(arr, data, 0, n-1, 0, r);
}
/* arr[] ---> Input Array
data[] ---> Temporary array to
store current combination
start & end ---> Staring and
Ending indexes in arr[]
index ---> Current index in data[]
r ---> Size of a combination to be printed */
void combinationUtil(int arr[], int data[], int start, int end,
int index, int r)
{
// Current combination is ready
// to be printed, print it
if (index == r)
{
for (int j = 0; j < r; j++)
cout << data[j] << " ";
cout << endl;
return;
}
// replace index with all possible
// elements. The condition "end-i+1 >= r-index"
// makes sure that including one element
// at index will make a combination with
// remaining elements at remaining positions
for (int i = start; i <= end && end - i + 1 >= r - index; i++)
{
data[index] = arr[i];
combinationUtil(arr, data, i+1,
end, index+1, r);
}
}
// Driver code
int main()
{
int arr[] = {1, 2, 3, 4, 5};
int r = 3;
int n = sizeof(arr)/sizeof(arr[0]);
printCombination(arr, n, r);
}
`
I'm doing a fairly easy HackerRank test which asks the user to write a function which returns the minimum number of swaps needed to sort an unordered vector in ascending order, e.g.
Start: 1, 2, 5, 4, 3
End: 1, 2, 3, 4, 5
Minimum number of swaps: 1
I've written a function which works on 13/14 test cases, but is too slow for the final case.
#include<iostream>
#include<vector>
using namespace std;
int mimumumSwaps(vector<int> arr) {
int p = 0; // Represents the (index + 1) of arr, e.g. 1, 2, ..., arr.size() + 1
int swaps = 0;
for (vector<int>::iterator i = arr.begin(); i != arr.end(); ++i) {
p++;
if (*i == p) // Element is in the correct place
continue;
else{ // Iterate through the rest of arr until the correct element is found
for (vector<int>::iterator j = arr.begin() + p - 1; j != arr.end(); ++j) {
if (*j == p) {
// Swap the elements
double temp = *j;
*j = *i;
*i = temp;
swaps++;
break;
}
}
}
}
return swaps;
}
int main()
{
vector<int> arr = { 1, 2, 5, 4, 3 };
cout << mimumumSwaps(arr);
}
How would I speed this up further?
Are there any functions I could import which could speed up processes for me?
Is there a way to do this without actually swapping any elements and simply working out the min. swaps which I imagine would speed up the process time?
All permutations can be broken down into cyclic subsets. Find said subsets.
Rotating a subset of K elements by 1 takes K-1 swaps.
Walk array until you find an element out of place. Walk that cycle until it completes. Advance, skipping elements that you've put into a cycle already. Sum (size-1) for each cycle.
To skip, maintain an ordered or unordered set of unexamined items, and fast remove as you examine them.
I think that gives optimal swap count in O(n lg n) or so.
#include <bits/stdc++.h>
#include <vector>
#include <algorithm>
using namespace std;
int minimumSwaps(vector<int> arr)
{
int i,c,j,k,l;
j=c=0;
l=k=arr.size();
while (j<k)
{
i=0;
while (i<l)
{
if (arr[i]!=i+1)
{
swap(arr[i],arr[arr[i]-1]);
c++;
}
i++;
}
k=k/2;
j++;
}
return c;
}
int main()
{
int n,q;
cin >> n;
vector<int> arr;
for (int i = 0; i < n; i++)
{
cin>>q;
arr.push_back(q);
}
int res = minimumSwaps(arr);
cout << res << "\n";
return 0;
}
I am writing a function that takes in a pointer that points to an array that is dynamically allocated, in addition to the length of the array. I am trying to find the second smallest sum of it's contiguous sub arrays.
I have been writing code to calculate the second smallest value in an array, and also a piece of code that calculates the sum of all the contiguous sub arrays. I was hoping that I would be able to "merge" these two pieces together to get what my desired end result, but I am getting stuck. I would really appreciate any help.
Thank you.
#include <iostream>
using namespace std;
int secondSmallestSum(int *numbers,int length)
{
//Below shows the sum of all contiguous sub arrays.
for(i = 0; i<= length; ++i)
{
int sum = 0;
for(int j = i; j <= length; ++j)
{
sum+=*(numbers+j);
}
}
//Below calculates the second smallest element in an array
int smallest, secondsmallest;
if (*numbers < *(numbers+1))
{
smallest = *numbers;
secondsmallest = *(numbers+1) ;
}
else {
smallest = *(numbers+1) ;
secondsmallest = *(numbers) ;
}
for (i = 2; i < length; i++) {
if (*(numbers+i) < smallest)
{
secondsmallest = smallest;
smallest = *(numbers+i);
}
else if (*(numbers+i) < secondsmallest)
{
secondsmallest = *(numbers+i);
}
}
}
You can do something like this (of course you need to add range checking).
#include <iostream>
#include <vector>
#include <algorithm>
int main(int argc, char** argv) {
std::vector<int> v{3, 1, 4, 5, 6, 2};
std::nth_element(v.begin(), v.begin() + 1, v.end());
std::cout << "The second smallest element is " << v[1] << "\n";
}
Note: using nth_element will change the order of the elements in the vector.
Correct me if I understand you wrong,
by looking at "find the second smallest sum of it's contiguous sub arrays" and the code you posted, I'm assuming your logic is
calculate all sums of all possible contiguous sub arrays
find the second smallest value in the sums
Actually there is a well known algorithm, Kadane's algorithm, that serves a similar purpose (only Kadane's finds THE smallest, not second smallest). You may want to Google it to find more.
Back to your question, I believe the following code does what you want. The code is a variant of Kadane's algorithm.
#include <climits> // for INT_MAX
int findSecondMinOfContiguousSubarray(int arr[], int n)
{
// to store the minimum value that is ending
// up to the current index
int min_ending_here = INT_MAX;
int min = INT_MAX; // absolute min
int min_second = INT_MAX - 1; // second min <- this is what you want
// traverse the array elements
for (int i = 0; i<n/*it is <, not <=*/; i++)
{
// if min_ending_here > 0, then it could not possibly
// contribute to the minimum sum further
if (min_ending_here > 0)
min_ending_here = arr[i];
// else add the value arr[i] to min_ending_here
else
min_ending_here += arr[i];
// update min and min_second
if (min_second > min_ending_here) {
if (min > min_ending_here) {
min_second = min;
min = min_ending_here;
}
else {
min_second = min_ending_here;
}
}
}
return min_second;
}
BTW, I think your code (the piece under //Below shows the sum of all contiguous sub arrays.) can not find all contiguous sub arrays.
An example, arr={1, 2, 3}, your code only consider {1,2,3}, {2,3} and {3} as contiguous sub arrays, while in fact {1,2} should also be considered.
Brutal force o(n^2) complexity (in C++ style not C style):
template<typename Container, typename Func>
void forEachSubrange(Container &container, Func &&f)
{
for (auto subBegin = container.begin(); subBegin != container.end(); ++subBegin)
{
auto subEnd = subBegin;
do {
++subEnd;
f(subBegin, subEnd);
} while (subEnd != container.end());
}
}
int secondSmallestSubrangeSum(const std::vector<int> &a)
{
int firstSum = 0; // empty sub range has zero sum
int secondSum = 0;
forEachSubrange(a, [&firstSum, &secondSum](auto b, auto e) {
auto sum = std::accumulate(b, e, 0);
if (sum < firstSum) {
secondSum = firstSum;
firstSum = sum;
} else if (sum < secondSum) {
secondSum = sum;
}
});
return secondSum;
}
I'm sure it is possible to achieve o(n).
https://wandbox.org/permlink/9cplKBIpfZBPpZ27
or more talkative https://wandbox.org/permlink/X21TdH6xtbMLpV19
I have to sort a vector N into M equals parts(M less than N).
But those equal parts have to be in the middle. If I have parts that are not equal i need to put them in the first and/or last element.Difference between first and last has to be minimal. I have managed to make a sort of that function. Function is making new vector(sizeof(M)) and inside stores number of parts from vector N.
ex. 10/7 vector M [1 1 2 2 2 1 1] 1+1+2+2+2+1+1=10 into 7 parts. Meaning I am taking n or n+1 objects for vector N and storing index in vector M. Values inside do not have to be equal.
Now I am having trouble because my deviations can only be first and last element.
And also i am having problems whit for
ex. 12/9 because i get M[1 1 1 2 2 2 1 1 1 ]
but if I can only have first and last as different
then it should be like M[3 1 1 1 1 1 1 1 2]
So my question : Is there any better way of making this?
#include "stdafx.h"
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
int N = 12; // size of vector
int M = 9; // numbers of divisions
static void subsizes(int vecSize, int subCount, vector<int> &v)
{
int baseSize = vecSize / subCount;
int bumps = vecSize % subCount;
int i,n=0,nPlus,counterPlus=0,counterN,counterLeft;
vector<int> temp(subCount); // for new results
vector<int> proba(subCount);
for (i = 0; i < subCount; i++) //dividing to n, n+1 and placing them in vector
{
temp[i]= baseSize + (i < bumps);
}
for (i=0; i<subCount; i++) // finding what numbers are n, n+1
{
nPlus=temp[i];
if(n==0 && n<nPlus){
n=nPlus;}
}
for(i=0; i<subCount;i++) //counting n, n+1
{
if(nPlus==temp[i])counterPlus++;
}
counterN=subCount-counterPlus;
counterLeft=counterPlus-2;
for(i=0; i<counterPlus/2; i++) //placing them in right order
temp[i]=nPlus;
for(i=counterPlus/2; i<counterPlus/2+counterN; i++)
temp[i]=n;
for(i=counterPlus/2+counterN; i<subCount; i++)
temp[i]=nPlus;
cout<<endl<<"Divided vector is :"<<endl; //printing results
for(i=0; i<subCount;i++)
{
int part = temp[i];
cout<<"At : vector["<<i<<"] nubmer of objects is --- "<<part<<endl;
}
putchar('\n');
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vec(N);
int vecSize = vec.size(); //length of original vector
int subCount=M; //number of sub-vectors parts
generate(vec.begin(), vec.end(), rand); // filling vector with C function rand()
cout<<"Vector is [ ";
for (auto i : vec) // printing out a vector
{
cout<<i<<" ";
}
cout<<"]"<<endl;
subsizes(vecSize,subCount,vec); // calling funciton that divideds and print results
system("PAUSE");
return 0;
}
You are complicating this, a lot.
If I understand you correctly
you want to take a vector of size N and divide it into M parts
Each of the M parts should have the same length
If there is remaining elements in N, you want to distribute the remainder to extra sub-parts at the beginning and end
Your output is a vector of the sizes of sub-parts
edit: it seems my assumption of "you want to distribute the remainder to extra sub-parts at the beginning and end" was wrong
If that is indeed what you want then you can just do this
void subsizes(int vecSize, int subCount, vector<int> &v)
{
int regular_size = (vecSize+2) / subCount;
int remainder = vecSize - regular_size * subCount;
vector<int> sizes(subCount, regular_size);
int front_remainder = remainder - (remainder / 2);
int back_remainder = remainder / 2;
sizes.front() += front_remainder;
sizes.back() += back_remainder;
for (int i = 0; i<sizes.size(); i++)
{
int part = sizes[i];
cout << "At : vector[" << i << "] nubmer of objects is --- " << part << endl;
}
putchar('\n');
}
I'm not sure I have a complete grip on your problem, but it appears that you are allowed to change the elements contained in vec. In which case, this is probably what you are looking for:
void subsizes(vector<int>& vec)
{
if(vec.size() > 1) // Don't do anything if there aren't at least 2 elements
{
// Get the sum of all the elements,
// but we're going to be adding back in 1s in every element but the last
// so subtract (vec.size() - 1) from this total.
// This is done by initializing accumulate to 1 - vec.size()
int last = accumulate(vec.begin(), vec.end(), 1 - vec.size());
// Now put 1s in all the elements
fill(vec.begin(), vec.end(), 1);
// Change the last element to the value accumulated in last
vec.back() = last;
}
}