Finding the number of nodes at each level during bfs - java

You have been given a Tree consisting of N nodes. A tree is a fully-connected graph consisting of N nodes and N−1 edges. The nodes in this tree are indexed from 1 to N. Consider node indexed 1 to be the root node of this tree. The root node lies at level one in the tree. You shall be given the tree and a single integer x . You need to find out the number of nodes lying on level x.
Input Format
The first line consists of a single integer N denoting the number of nodes in the tree. Each of the next n−1 lines consists of 2 integers a andb denoting an undirected edge between node a and node b. The next line consists of a single integer x.
Output Format
You need to print a single integers denoting the number of nodes on level x.
below is the code snippet i wrote and its not correct. Please help me find the error.
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
public class LevelNodes {
public static ArrayList[] adj;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
boolean[] visites = new boolean[N];
ArrayList[] adj = new ArrayList[N];
for(int j=0;j<N;j++){
adj[j] = new ArrayList();
}
for(int i = 0;i < (N-1) ;i++){
int a = sc.nextInt();
int b = sc.nextInt();
adj[a-1].add(b);
adj[b-1].add(a);
}
int level = sc.nextInt();
int counter = 0;
LinkedList list = new LinkedList();
list.add(1);
counter++;
while(!list.isEmpty()){
int n = (Integer) list.poll();
for(int x = 0; x< adj[n-1].size();x++){
list.add(adj[n-1].get(x));
}
counter++;
if(counter == level){
System.out.println(list.size());
break;
}
}
}
}

There are a number of problems in your code:
The first problem is that your code might not terminate. This is because you are adding both edges u->v and v->u to your adjacency list. So whenever you poll u from the list and add its neighbors, you are going to add v to the list. Likewise, whenever you poll v and add its neighbors, you are going to add back u to the list. You need to maintain a boolean array visited and set visited[u]=true whenever you add u to the list. This way you can add only unvisited nodes to your scan list.
Another major problem is in the while loop. You are incrementing the level counter variable counter++; whenever you visit a new node. Consider the tree below and assume we need to find the number of nodes at level 2 (the last level).
1
/ \
2 3
/ \ / \
4 5 6 7
Initially your list contains 1 and counter=1. In the first iteration, you poll 1 from the list and add its neighbors: 2 and 3. At this stage, counter=2. In the next two iterations, you are going to remove 2 then 3 from the list, add their neighbors, and increment counter each time. So by the time you reach the second level, counter would be equal to 4. The If statement would never be executed.
To fix this, you have to increment counter iff you are done processing all the node at the current level. A simple (untested) way to do that is to use a second temporary list to hold the neighbors of all the nodes at the current level. Then, whenever the original list is empty, you know that you have processed all the nodes at the current level. Here, you increment counter and move all the nodes from the temporary list to the main list.
while(!list.isEmpty()){
int n = (Integer) list.poll();
for(int x = 0; x< adj[n-1].size();x++){
tmpList.add(adj[n-1].get(x));
}
if(list.isEmpty()) {
if(counter == level){
System.out.println(tmpList.size());
break;
}
list.addAll(tmpList);
tmpList.clear();
counter++;
}
}

Related

Permutation matrix with dynamic variable (days), each day should "generate" one for-loop?

I want to make a permutation matrix using a dynamic variable (days).
My current code has 3 loops (for 3 days), and if I wanted to add another day or delete one day, I would have to add/delete one complete for-loop.
public static ArrayList<ArrayList<Integer>> computePermutations(int stops, int days) {
int maxPerDay = stops - (days - 1);
ArrayList<ArrayList<Integer>> permutationMatrix = new ArrayList<ArrayList<Integer>>();
for (int m = 1; m <= maxPerDay; m++) {
for (int n = 1; n <= maxPerDay; n++) {
for (int o = 1; o <= maxPerDay; o++) {
if (m + n + o == stops) {
ArrayList<Integer> possibleSolution = new ArrayList<Integer>(Arrays.asList(m, n, o));
permutationMatrix.add(possibleSolution);
}
}
}
}
return permutationMatrix;
}
I also need to update the line: ArrayList<Integer> possibleSolution = new ArrayList<Integer>(Arrays.asList(m, n, o));, so the parameters (m, n, o) change depending on the amount of days.
Your question in essence can be summarized as follows
If I have to compute the permutation of n elements, do I need n embedded for cycles?
And the answer is no. It is solvable with embedding n cycles, you are correct in observing that, but it is not necessary, nor advisable. The problem with this kind of solution is that your program will assume in advance the number of items to permutate and will have difficulty in handling the case when the number of elements to permutate is dynamic.
First of all, you need to understand what a stack is, that is a Last In, First Out (LIFO) data-structure, which means that you can always push elements to its top, but whenever you need to take out an element, you take it to the top.
So, you need to implement the following (I'm not taking the fun of the actual implementation):
you create an empty stack
you add 1 to its top
while your stack is not empty
if you are not at the last element, push the first element that's not already in the stack
else if you are at the last element, then you have found a new permutation and
while stack.top is n or there is no stack.top < i <= n that's not already in the stack, stack.pop
if the stack is empty, then the algorithm ends
else
current <- stack.top
stack.push(the first element that's higher than current and is not in the stack)
So, you are able to use one main loop and inside that loop you will only need some loops to find the next unused element instead of a loop for every index.

I am implementing a Minimum Spanning Forrest algorithm in Java. But stuck on how to write a loop

Algorithm:
input : Graph G
output: Set of MSTs T
begin
T=null;
E=G.Edges;
for all vertices in G,
Create a tree t having single vertex b
add t to T
end for
repeat
Find an edge e ∈ E having minimum weight
such that one end belongs to t ∈ T and the other
end does not belongs to any of the trees in T
Add e to t
until e = NULL
I'm stuck on the logic for the highlighted block.
I've used simple objects for vertex,edge and tree. And for their sets, used array of Objects.
I have the code:
Tree[] findMSF(){
T=new Tree[numofMST];
E=new Edge[C.v.length];
for(int i=0;i<E.length;i++){
E[i]=C.e[i];//E ← C.Edges
}
for(int i=0;i<B.length;i++){
t=new Tree(B[i].v);//Create a tree t having single vertex b
T[i]=t;// T ← T U t
}
do{
e=find_e(E);
}while(e!=null);
return T;
}
I need implementation for find_e(E);
Use a for loop.
for (int i = 1; i < 10; i++)
{
Your code
}
To change the number of times it repeats, change 10 to another number.

Solving a challenge in JAVA. The challenge is mentioned below in the description. The logical bug I am facing is also in the description below

Lukáš really likes orienteering, a sport that requires locating control points in rough terrain. To entertain the NWERC participants Lukáš wants to organize an orienteering race. However, it would be too harsh for the participants to be outdoors in this cold Swedish November weather, so he decided to jump on the new trend of indoor races, and set the race inside the B building of Linköping University.
Lukáš has already decided on the locations of the control points. He has also decided on the exact length of the race, so the only thing remaining is to decide in which order the control points should be visited such that the length of the total race is as he wishes. Because this is not always possible, he asks you to write a program to help him.
Input Format
The input consists of:
one line with two integers n (2 ≤ n ≤ 14) and L (1 ≤ L ≤ 1015), the number of control points and the desired length of the race, respectively;
n lines with n integers each. The jth integer on the ith line, dij , denotes the distance between control point i and j (1 ≤ dij ≤ L for i 6= j, and dii = 0). For all 1 ≤ i, j, k ≤ N it is the case that dij = dji and dij ≤ dik + dkj .
Output Format
Output one line with “possible” if it is possible to visit all control points once in some order and directly return to the first one such that the total distance is exactly L, and “impossible” otherwise.
Sample Input
3 5
0 1 3
1 0 3
4 1 0
Sample Output
possible
The problem with the code is that the for loop in else loop of function checkscenario() only considers the first iteration and returns false as a result. It doesn't check the next iteration which will return true and thus give the proper solution.
Lets use the sample input for the explanation. Initially, the function gets value of the parameters as follows :-
controlptsleft = {0,1,2,3}
//These are the control pts which haven't been visited.
index = 0;
//This is the control pt that I am at.
controlmatrix =
0 1 3
1 0 3
4 1 0
L = 5
//The desired length.
sum = 0
//Till now we haven't trailed the control pts. So, sum = 0.
public static boolean checkscenario(ArrayList<Integer> controlptsleft, int index, int[][] controlmatrix, int L, int sum){
int row = controlptsleft.get(index);
//row stores the value in the ArrayList controlptsleft at the index.
controlptsleft.remove(index);
//The controlpt is removed. The first time 0 will be removed from arrayList controlptsleft.
if(controlptsleft.isEmpty()){
//When the ArrayList controlptsleft is empty, we have to go back to the first controlflag.
int temp = controlmatrix[row][0];
//temp stores the distance between the control flag where we are at and the starting control flag.
if(L == (sum + temp))
return true;
}
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
//temp stores the distance between the control flag where we are at and the whatever controlflag we get during the iteration.
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
//Here, i is sent so that when it enters the function again the index i (along with the value) in ArrayList tempList will be deleted.
if(finalres)
return true;
}
}
return false;
}
Just in case someone out there wants to know, I figured out the answer for this challenge.
First of all, i would like to thank Hanno Binder for that comment. I realized where I went wrong.
Inside the else loop of the function checkscenario
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
What I did was, I directly copied the reference of controlptsleft to tempList. I realized the bug and I instead initialized tempList and used .addAll to put all the values from controlptsleft to tempList.
The following code illustrates what I meant above.
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = new ArrayList<Integer>();
tempList.addAll(controlptsleft);
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
}
If someone has a better solution in JAVA for the challenge mentioned above. Feel free to post their code, so I could learn how to code better.

Print Specific nodes at a every level calculated by a given function

In an interview, i was given a function:
f(n)= square(f(n-1)) - square(f(n-2)); for n>2
f(1) = 1;
f(2) = 2;
Here n is the level of an n-array tree. f(n)=1,2,3,5,16...
For every level n of a given N-Array I have to print the f(n) node at every level. For example:
At level 1 print node number 1 (i.e. root)
At level 2 print node number 2 (from left)
At level 3 print node number 3 (from left)
At level 4 print node number 5... and so on
If the number of nodes(say nl) at any level n is less than f(n), then have to print node number nl%f(n) counting from the left.
I did a basic level order traversal using a queue, but I was stuck at how to count nodes at every level and handle the condition when number of nodes at any level n is less than f(n).
Suggest a way to proceed for remaining part of problem.
You need to perform Level Order Traversal.
In the code below I am assuming two methods:
One is getFn(int level) which takes in an int and returns the f(n) value;
Another is printNth(int i, Node n) that takes in an int and Node and beautifully prints that "{n} is the desired one for level {i}".
The code is simple to implement now. Comments explain it like a story...
public void printNth throws IllegalArgumentException (Node root) {
if (root == null) throw new IllegalArgumentException("Null root provided");
//Beginning at level 1 - adding the root. Assumed that levels start from 1
LinkedList<Node> parent = new LinkedList<>();
parent.add(root)
int level = 1;
printNth(getFn(level), root);
//Now beginning from the first set of parents, i.e. the root itself,
//we dump all the children from left to right in another list.
while (parent.size() > 0) { //Last level will have no children. Loop will break there.
//Starting with a list to store the children
LinkedList<Node> children = new LinkedList<>();
//For each parent node add both children, left to right
for (Node n: parent) {
if (n.left != null) children.add(n.left);
if (n.right != null) children.add(n.right);
}
//Now get the value of f(n) for this level
level++;
int f_n = getFn(level);
//Now, if there are not sufficient elements in the list, print the list size
//because children.size()%f(n) will be children.size() only!
if (children.size() < f_n) System.out.println(children.size());
else printNth(level, children.get(f_n - 1)); //f_n - 1 because index starts from 0
//Finally, the children list of this level will serve as the new parent list
//for the level below.
parent = children;
}
}
Added solution here
I have used queue to read all nodes at a particular level, before reading the nodes checking if given level(n) is equal to current level then checking size of the queue is greater than f(n) then just read f(n) nodes from queue and mark it as deleted otherwise perform mod operation and delete the node nl%f(n).

Finding a powerset from a linked list

I am looking for some help with my Java programming assignment. Using a linked list, I need to print out its power set. For example, the set {1,2,3} should print out
{{},{1}{1,2}{1,3}{1,2,3}{2}{2,3}{3}}. The number of elements in the power set is 2^n.
This needs to be done by calling
HeadNode.PrintPowerSet();
where HeadNode is the first element in the linked list.
I have tried a few things and nothing is working that well. I think the best way to do it would be to call the method recursively until the end sentinel is reached and then work backwards, adding the elements that are left. Sorry I can't post more code or more ideas because nothing I have tried has worked that well. Thanks in advance.
EDIT:
This is the non working code. It returns the set {{1,2,3}{2,3}{3}}
public RSet powerSet()
{
if (this == EMPTY_SET)
return EMPTY_SET;
RSet q = new RSet();
if (q != EMPTY_SET)
q.next = next.powerSet();
q = new RSet(this, n, q.next);
return q;
}
EMPTY_SET is the end sentinel. I've tried writing it out by hand. It helps but I still can't get it. Also this class, RSet, is essentially just a linked list node.
Just iterate all the numbers from 0 to 2^n - 1. Each defines an element of the power set:
The list defines a fixed index on your set. For each number, create a new set. Considering the number in its binary format, add the item in the original set at index i to the set if the bit at index i is 1 and don't add it otherwise.
Then, for each number you will have a set that is an element of the power set.
int n = list.size();
Set<Set<T>> powerSet = new HashSet<Set<T>>();
for( long i = 0; i < (1 << n - 1); i++) {
Set<T> element = new HashSet<T>();
for( int j = 0; j < n; j++ )
if( (i >> j) % 2 == 1 ) element.add(list.get(j));
powerSet.add(element);
}
return powerSet;

Categories