Computing permutations using a number of elements - c++

I am trying to generate all possible permutations of a set of elements. The order doesn't matter, and elements may be present multiple times. The number of elements in each permutation is equal to the total number of elements.
A basic recursive algorithm for computing permutations following the schema (as I am writing in C++, the code will look similar to it):
elems = [0, 1, .., n-1]; // n unique elements. numbers only exemplary.
current = []; // array of size n
perms(elems, current, 0); // initial call
perms(array elems, array current, int depth) {
if(depth == elems.size) print current;
else {
for(elem : elems) {
current[depth] = elem;
perms(elems, current, depth+1);
}
}
}
Would produce a large number of redundant sequences, e.g.:
0, 0, .., 0, 0
0, 0, .., 0, 1 // this
0, 0, .., 0, 2
. . . . .
. . . . .
0, 0, .., 0, n-1
0, 0, .., 1, 0 // is the same as this
. . . . . // many more redundant ones to follow
I tried to identify when exactly generating values can be skipped, but have so far not found nothing useful. I am sure I can find a way to hack around this, but I am also sure, that there is a rule behind this which I just haven't managed to see.
Edit: Possible solution+
elems = [0, 1, .., n-1]; // n unique elements. numbers only exemplary.
current = []; // array of size n
perms(elems, current, 0, 0); // initial call
perms(array elems, array current, int depth, int minimum) {
if(depth == elems.size) print current;
else {
for(int i=minimum; i<elems.size; i++) {
current[depth] = elems[i];
perms(elems, current, depth+1, i);
}
}
}

Make your first position varies from 0 to n. Then make your second position to 1. Then make your first position varies from 1 to n. Then set second at 2 --> first from 2 to n and so on.

I believe one such rule is to have the elements in each sequence be in non-decreasing order (or non-increasing, if you prefer).

Related

Find the first element that is n times larger than current element in a list

It is easy to come up with an O(n) algorithm to solve this very famous question:
For every element in the list, find the first element that is larger than it. This can be done using a stack. But, what if I want to find the first element that is larger than n*current element?
More specifically:
Given an array [2, 5, 4, 7, 3, 8, 9, 6] and n = 2.
I want [5, -1, 9, -1, 8, -1, -1, -1]
For 2, 5 is the next element larger than n * 2, for 4, 9 is the next element larger than n * 4. For 5, there is no element larger than n * 5 so return -1 at that position.
Can we do better than O(n^2)?
I agree with OP that, the simple predicate of the O(N) algo might not work on the stack-based solution when looking for the first element > 2x in the remaining array.
I found a O(NlogN) solution for this btw.
It uses a Min-heap to maintain the frontier elements we are interested in.
Pseudo-code:
def get_2x_elements(input_list, multipler = 2):
H = [] #min-heap with node-values as tuples (index, value)
R = [-1 for _ in range(len(input_list))] # results-list
for index, value in enumerate(input_list):
while multiplier*H[0][1] < value:
minval = extractMinFromHeap(H)
R[minval[0]] = value
insertToMinHeap(H, (index, value))
return R
Complexity-analysis:
1. Insertion/Extraction from min-heap = O(logN)
2. Number of such operations = N
Total-complexity = O(NlogN)
PS: This assumes we need the first >2x element from the remaining part of the list.
Re:
I made a Java verion implementation of your idea. Thanks #Serial Lazer
private static class ValueAndIndexPair implements Comparable<ValueAndIndexPair>{
public final double value;
public final int index;
public ValueAndIndexPair(double value, int index) {
this.value = value;
this.index = index;
}
#Override
public int compareTo(ValueAndIndexPair other) {
return Double.compare(value, other.value);
}
}
public static double[] returnNextNTimeLargerElementIndex(final List<Double> valueList, double multiplier) {
double[] result = new double[valueList.size()];
PriorityQueue<ValueAndIndexPair> minHeap = new PriorityQueue<>();
// Initialize O(n)
for (int i = 0; i < valueList.size(); i++) {
result[i] = -1.0;
}
if (valueList.size() <= 1) return result;
minHeap.add(new ValueAndIndexPair(valueList.get(0) * multiplier, 0));
for (int i = 1; i <valueList.size(); i++) {
double currentElement = valueList.get(i);
while (!minHeap.isEmpty() && minHeap.peek().value < currentElement) {
result[minHeap.poll().index] = currentElement;
}
minHeap.add(new ValueAndIndexPair(currentElement * multiplier, i));
}
return result;
}
Sure, easily.
We just need a sorted version of the array (sorted elements plus their original index) and then we can do an efficient search (a modified binary search) that points us to the start of the elements that are larger than the current number (or a multiple of it, it doesn't matter). Those elements we can then search sequentially for the one with the smallest index (that is greater than the one of the current number, if so required).
Edit: It was pointed out that the algorithm may not be better than O(n²) because of the sequential search of the elements that satisfy the condition of being greater. This may be so, I'm not sure.
But note that we may build a more complex search structure that involves the index already, somehow. This is left as homework. :)
The stack-based solution offered at geeksforgeeks does not seem to maintain the order of the elements in the result even in its output:
input: int arr[] = { 11, 13, 21, 3 };
output:
11 -- 13
13 -- 21
3 -- -1
21 -- -1
After minor modification to find the first element which is greater N times than a current, this algorithm fails to detect 9 for the element 4 from the given example.
Online demo
input: int arr[] = { 2, 5, 4, 7, 3, 8, 9, 6 }; // as in this question
output:
2 * 2 --> 5
2 * 3 --> 8
6 -- -1
9 -- -1
8 -- -1
7 -- -1
4 -- -1
5 -- -1
Thus, initial assumption about existing solution with complexity O(N) is not quite applicable to the expected result.

Fastest sorting method for k digits and N elements, k <<< N

Question: There are n balls, they are labeled 0, 1, 2 and the order is chaotic, I want to sort them from small to large. Balls:
1, 2, 0, 1, 1, 2, 2, 0, 1, 2, ...
We must use the fastest way to solve and cannot use sort() function, I thought many ways like the bubble sort, inset sort, etc. But it is not fast. Is there an algorithm that makes the time complexity is O(logn) or O(n)?
given balls list A[] and length n
void sortBalls(int A[], int n)
{
//code here
}
Given the very limited number of item types (0, 1, and 2), you just count the number of occurrences of each. Then to print the "sorted" array, you repeatedly print each label the number of times it occurred. Running time is O(N)
int balls[N] = {...}; // array of balls: initialized to whatever
int sorted_balls[N]; // sorted array of balls (to be set below)
int counts[3] = {}; // count of each label, zero initialized array.
// enumerate over the input array and count each label's occurance
for (int i = 0; i < N; i++)
{
counts[balls[i]]++;
}
// sort the items by just printing each label the number of times it was counted above
int k = 0;
for (int j = 0; j < 3; j++)
{
for (int x = 0; x < counts[j]; x++)
{
cout << j << ", "; // print
sorted_balls[k] = j; // store into the final sorted array
k++;
}
}
If you have a small number of possible values known in advance, and the value is everything you need to know about the ball (they carry no other attributes), "sorting" becomes equivalent to "counting how many of each value there are". So you generate a histogram - an array from 0 to 2, in your case - go through your values and increase the corresponding count. Then you generate an array of n_0 balls with number 0, n_1 balls with number 1 and n_2 with number 2, and voila, they're sorted.
It's trivially obvious that you cannot go below O(n) - at the very least, you have to look at each value once to count it, and for n values, that's n operations right away.

Is there a way using divide and conquer to calculate how many times array has changed sign

Suppose there is an array A = {1, -1, 1, 1, 1, -1, 1} is there a way to calculate how many times the element of the array changed sign using divide and conquer? e.g: from -1 to 1 and 1 to -1.
I have tried to implement a solution that divides the array into 2 sub-array and calculate whether the last element of the left sub array multiplied by the right element of the right sub array is less than 0, in that case the sign changed.
This is the pseudocode I'm trying to implement:
Find Number of Roots(vector V)
n = V.size()
if n <= 1
return 0
end if
else
number_of_roots = 0
lower_half = Roots(V[1...n/2])
upper_half = Roots(V[n/2+1...n])
if (lower_half.back() * upper_half.front() < 0)
number_of_roots++
return number_of_roots
end else
end program

C++ : Inserting Operator + and - In an array and check if it is possible to create n

Problem : If you were given a number n, you will have an array with (n-1) index. with the 1st index containing 1, 2nd index containing 2, and n-1 index containing n-1. Given those sets of numbers, How can one check when + or -, the array can be equal to n?
Example :
n = 3, Array = {1,2}
+1 +2 = 3 (True)
n = 4, Array = {1,2,3}
-1 + 2 + 3 = 4 (True)
n = 5, Array = {1,2,3,4}
No possible combination
I tried too long to think about it and still haven't come up with the right answer :(
If you ale looking for simple solvable/not solvable answer, then it seems the answer if very simple
(sum - n) % 2 != 0 // => non-solvable
Here is result of an experiment:
When n gets larger it becomes easier to subtract necessary sum and there are plenty of possible solutions.

Bijective mapping of integers

English is not my native language: sorry for my mistakes. Thank you in advance for your answers.
I'm learning C++ and I'm trying to check to what extent two sets with the same number of integers--in whatever order--are bijective.
Example :
int ArrayA [4] = { 0, 0, 3, 4 };
int ArrayB [4] = { 4, 0, 0, 3 };
ArrayA and ArrayB are bijective.
My implementation is naive.
int i, x=0;
std::sort(std::begin(ArrayA), std::end(ArrayA));
std::sort(std::begin(ArrayB), std::end(ArrayB));
for (i=0; i<4; i++) if (ArrayA[i]!=ArrayB[i]) x++;
If x == 0, then the two sets are bijective. Easy.
My problem is the following: I would like to count the number of bijections between the sets, and not only the whole property of the relationship between ArrayA and ArrayB.
Example :
int ArrayA [4] = { 0, 0, 0, 1 }
int ArrayB [4] = { 3, 1, 3, 0 }
Are the sets bijective as a whole? No. But there are 2 bijections (0 and 0, 1 and 1).
With my code, the output would be 1 bijection. Indeed, if we sort the arrays, we get:
ArrayA = 0, 0, 0, 1;
ArrayB = 0, 1, 3, 3.
A side-by-side comparaison shows only a bijection between 0 and 0.
Then, my question is:
Do you know a method to map elements between two equally-sized sets and count the number of bijections, whatever the order of the integers?
Solved!
The answer given by Ivaylo Strandjev works:
Sort the sets,
Use the std::set_intersection function,
Profit.
You need to count the number of elements that are contained in both sets. This is called set intersection and it can be done with a standard function - set_intersection, part of the header algorithm. Keep in mind you still need to sort the two arrays first.