I need to shuffle an array so that all array elements should change their location.
Given an array [0,1,2,3] it would be ok to get [1,0,3,2] or [3,2,0,1] but not [3,1,2,0] (because 2 left unchanged).
I suppose algorithm would not be language-specific, but just in case, I need it in C++ program (and I cannot use std::random_shuffle due to the additional requirement).
What about this?
Allocate an array which contains numbers from 0 to arrayLength-1
Shuffle the array
If there is no element in array whose index equals its value, continue to step 4; otherwise repeat from step 2.
Use shuffled array values as indexes for your array.
For each element e
If there is an element to the left of e
Select a random element r to the left of e
swap r and e
This guarantees that each value isn't in the position that it started, but doesn't guarantee that each value changes if there's duplicates.
BeeOnRope notes that though simple, this is flawed. Given the list [0,1,2,3], this algorithm cannot produce the output [1,0,3,2].
It's not going to be very random, but you can rotate all the elements at least one position:
std::rotate(v.begin(), v.begin() + (rand() % v.size() - 1) + 1, v.end());
If v was {1,2,3,4,5,6,7,8,9} at the beginning, then after rotation it will be, for example: {2,3,4,5,6,7,8,9,1}, or {3,4,5,6,7,8,9,1,2}, etc.
All elements of the array will change position.
I kind of have a idea in my mind hope it fits your application. Have one more container and this container will be
a "map(int,vector(int))" . The key element will show index and the second element the vector will hold the already used values.
For example for the first element you will use rand function to find which element of the array you should use.Than you will check the map structure if this element of the array has been used for this index.
Related
we have been given k sorted arrays. Lets say k =3
a1={1,4,7} a2={3,5} a3={2,6,7} now we are supposed to merge these 3 arrays in sorted order. Hence the output will be {1,2,3,4,5,6,7,7}.
Now in the tutorial that i am following they have maintained an index and used pairs to solve this question using min heaps.
But my question is that since min heaps stores the elements in sorted order so can we just simply use the push function of min heap for all the elements from k arrays and then at the end printing the min heap?? instead of keeping index and making pairs? in c++?
Sure, but that's slow. You are throwing away the work that has already gone into the input arrays (that they are already sorted) and basically making the sorted array from the unsorted collection of all the elements. Concretely, if all the input arrays have average length n, then you perform k*n inserts into the heap, and then you extract the minimum k*n times. The heap operations have complexity O(log(k*n)). So the entire algorithm takes O(k*n*log(k*n)) time, which you may recognize as the time it takes to sort an unsorted array of size k*n. Surely there's a better way, because you know the input arrays are sorted.
I presume the given solution is to construct k "iterators" into the arrays, place them into a heap sorted by the value at each iterator, and then repeatedly remove the least iterator, consume its value, increment it, and place it back in the heap. The key is that the heap (which is where all the work is happening) is smaller: it contains only k elements instead of k*n. This makes every operation on the heap faster: now the heap operations in this algorithm are O(log k). The overall algorithm is now O(k*n*log k), an improvement.
I think this Algorithm is what you are looking for
Algorithm:
Create a min Heap and insert the first element of all k arrays. Run a
loop until the size of MinHeap is greater than zero. Remove the top
element of the MinHeap and print the element. Now insert the next
element from the same array in which the removed element belonged. If
the array doesn’t have any more elements, then replace root with
infinite.After replacing the root, heapify the tree.
And about time needed: O( n * k * log k), Insertion and deletion in a Min Heap requires log k time. So the Overall time compelxity is O( n * k * log k)
But my question is that since min heaps stores the elements in sorted
order so can we just simply use the push function of min heap for all
the elements from k arrays and then at the end printing the min heap??
The main recursive rule for min-heap: left and right child should be less than parent. It does not mean that left child should be less than parent of right side of tree. Attached image show min-heap. But this min-heap is not finally sorted array
It's a simple thing that I am doing but it doesn't work as I expected.
int main(){
vector<list<int>> adjList(3);
adjList[0].push_back(1);
adjList[0].push_back(2);
adjList[1].push_back(3);
adjList[1].push_back(0);
adjList[2].push_back(4);
cout << "Original graph...\n";
printGraph(adjList);
cout << "\nAfter deleting the zeroth index...\n";
adjList.erase(adjList.begin());
printGraph(adjList);
return 0;
}
Original graph...
0:1->2->NULL
1:3->0->NULL
2:4->NULL
After deleting the zeroth index...
0:3->0->NULL
1:4->NULL
I expected the zeroth index in my vector of list to be deleted. Instead, something weird happened where the second index got deleted and the elements in the list also got shuffled.
I am sure I am missing something basic here but just not able to figure out what that is.
Any help is much appreciated!
My bad. I realize now what's wrong. I was expecting to see the same indices after deletion but of course that is a wrong expectation. So the output is actually right just the indices moved around.
Original graph...
0:1->2->NULL
1:3->0->NULL
2:4->NULL
After deleting the zeroth index...
0:3->0->NULL (index 1 becomes 0)
1:4->NULL (index 2 becomes 1)
adjList.erase(adjList.begin()+1);
I expected the zeroth index in my vector of list to be deleted.
Your expectation is wrong.
adjList.begin()+1 is an iterator to the element at index 1. Therefore erasing that iterator will cause the element at index 1 to be erased (i.e. the second element).
adjList.begin() is an iterator to the element at the index 0, so if your intention is to erase that element, then that is the iterator that you would need to erase. Note however, that if you need to often erase the first element of the sequence, and need to keep the sequence in original order, then a vector is an inefficient choice. In such case, you might want to consider using a deque.
adjList.erase(adjList.begin());
I expected to get the below: 1:3->0->NULL 2:4->NULL
Your expectation is wrong.
A vector never skips any indices. If there are n elements in a vector, then those elements are in indices 0...n-1.
When you erase an element of a vector, the elements at greater indices are shifted to the left (this is why erasing from anywhere except at the end of the vector is slow).
I have a vector < vector <int> > like so:
v = {{1,2,3}, {4,2,1}, {3,1,1}....}}
All v's elements like v[0], v[1], v[2]... have the same size. There may be duplicate elements.
What I am trying to do is to find and delete vectors (like v[2]) that are "majorized" by another vector (like v[1]), i.e. all elements of v[1] are greater than/equal to the respective elements(in order of indices) in v[2].
A naive way of doing this would be to loop thorough v and compare each vector with another vector and further compare each element with another vector's element.
But I feel there must a better way to do this without getting O(n^3) in the number of elements of all the vectors in v.
If multiple vectors are equal, I need only one of them (i.e delete all except one). A random choice would be sufficient.
Any thoughts or ideas are appreciated!
This is called the maxima of a point set. For two and three dimensions, this can be solved in O(n log n) time. For more than three dimensions, this can be solved in O(n(log n)^(d − 3) log log n) time. For random points, a linear expected time algorithm is available.
Good day,
I have a logic problem that I'm stuck with.
I have a vector of vectors that contains an N number of integers. Think of it as a jagged array filled with integers.
For example:
vector<vector<int>> myVector
(lets say, these are the contents of the vector)
myVector[0] = {0,1} myVector[1] = {1,2} myVector[2] = {3,4,5}
myVector[3] = {4,5,6} myVector[4] = {7,8}
What I want to do is to combine vectors that share the same element. As you can see, myvector[0] and myvector[1] share the same element value '1', that also becomes true with myvector 2 and 3 since they share the same element value '4'. myVector[4] stays unchanged since it does not share any values with other vectors
My resulting product should be like this
newVector[0]= {0,1,2} newVector[1]= {3,4,5,6} newVector[2]= {7,8}
please help :)
One obvious and easy way to do this is:
pre-sort the individual vectors if necessary
iterate i through the vector<vector<int>>
iterator j through i+1..end()
use iterators k and l within the vectors *i and *j, advancing whichever of *k and *l has a lesser value until you find a shared value or reach an end(): if there was a shared value append *j to *i and re-sort, otherwise advance j
That's probably not the optimal solution performance wise, but you could implement/profile it and let us know if you must have something faster.
I am working on a magic square problem that uses a dynamic matrix of size n*n. It fills the matrix with numbers 1-n^2, and the sum of each row, column, and diagonal must be the same. One of the conditions of the algorithm is to check if an element in the matrix already had a number input in it during one of the loops. I am having problems checking if one of the elements in the matrix already had a number inputed in it, so I am wondering how to check if an element is empty.
Here is my code for that portion of the algorithm:
else if(matrix[row][col] != 0)
{
row = row + 2;
col--;
}
For some reason it triggers this if statement on the 5th iteration of the encompasing loop. I have worked it out on paper using the algorithm for a magic square, and the 5th iteration of the loop brings it to an empty element in the matrix. I thought that if an element is empty it holds the value 0? I appreciate any help as I am very confused. Thank you.
Array's in C and C++ are not empty by default. You need to explicitly set the elements to 0 or create the array in such a way that they are initialized to 0.
What you are facing is Undefined Behavior. The uninitialized array has some random(read garbage) values and accessing those results in a Undefined behavior.
Array's created at global scope or with a static qualifier will be initialized to 0 or you can use initialization provided built in by the language or you can explicitly set each element to 0.
There are multiple ways of doing so, the best one depends on what behavior you want to extract from the array.