I have already asked a question here. And I achieved the answer.
Actually, this is a kind of different path, i.e., I have two options for each level, up(1) or down(-1), and I have the n
level. Therefore I have 2^n
path.
Now in this current question, I want to select some desired paths. My desired paths have two conditions as follows.
The end of a given path reaches, let say,
1
. Thus, I want to select those paths which finally reach1
i.e., the sum of a given path withn
level is1
.I want to bound those paths in #1 between, let say,
9
and-9
. For example, I want to avoid the sum of9
up or9
down in sequence, which is bigger than9
and less than-9
.
Here is my attempt:
int popcount(unsigned x){
int c = 0;
for (; x != 0; x >>= 1)
if (x & 1)
c++;
return c;
}
void selected_path(vector<int> &d, int n){
d.clear();
int size = 1<<n;
d.resize(size);
for (int i = 0; i < size; ++i) {
d[i] = n-2.0*popcount(i);
}
}
In the above code, d[]
gives me all possible paths, i.e. 2^n
. But I want to select those paths with the above 2 conditions.
Edit: the answer but not efficient!
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
int data;
node *left, *right;
};
struct node *create(int x, int n, int limit){
struct node *newnode;
newnode = new node();
n++;
if(n==(limit+2)) return 0;
newnode->data = x;
x = newnode->data + 1;
newnode->left = create(x,n,limit);
x = newnode->data -1 ;
newnode->right = create(x, n,limit);
return newnode;
}
void inorder(std::vector<int> &d, node *root, vector<int> &stack, int uplimit, int downlimit){ //uplimit,downlimit
if(root == NULL) return;
stack.push_back(root->data);
inorder(d,root->left,stack,uplimit,downlimit);
if(root->left == 0 and root->right ==0){
if(stack[stack.size() -1] == 1){
int max=*max_element(stack.begin(), stack.end());
int min=*min_element(stack.begin(), stack.end());
if(max < uplimit and min > downlimit){
for(int i = 1; i < stack.size(); i++){
d.push_back(stack[i]);
}
}
}
}
inorder(d,root->right,stack,uplimit,downlimit);
stack.pop_back();
}
int main(){
int limit = 7;
struct node *root;
root = create(0,0,limit);
std::vector<int> stack;
std::vector<int> d;
int uplimit = 9;
int downlimit = -9;
inorder(d,root, stack,uplimit,downlimit);
stack.clear();
int n_path = int(d.size()/(limit));
for(int ip =0; ip < n_path; ip++){
for(int i = 1; i <=limit; i++){
cout << d[ip*(limit)+(i-1)] << "\t";
}
cout << endl;
}
}
A possible answer can be as above code. Here d[]
is a two-dimension array, which is the first one is the number of the paths, and the second dimension is the value of nodes during the path.
But the problem is that it is not efficient in terms of memory (if limit > 20
) due to the root-> data
saves all possible nodes, which is unnecessary.
I would highly appreciate it if one could give some idea to make it efficient