How to calculate the number of childern in a tree using recursion - java

I have designed a recursive algorithm to find the number of children in a string. The string is actually an array such as [1,0,1,0,1]. There three possible children of this string which are [0,0,1,0,1], [1,0,0,0,1] and [1,0,1,0,0]. Thus the criteria for creating the children is to decrement only one non-zero entry in the string. Since there are three non-zero entries in [1,0,1,0,1] so three possible children. Continuing in this fashion each children can now have two possible children and so on. The recursion stop when there is only one non-zero entry in the string.
This is my code:
public class Recursion {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] c={1,0,1,0,1};
System.out.println(num(c));
}
private static int num(int[] v){
if(numChildren(v)==1){
return 1;
}
else{
int[][] ge=children(v);
for(int[] e:ge){
return 1+num(e);
}
System.out.print("this return should never execute");
return 0;
}
}
private static int numChildren(int[] val){
int sum=0;
for(int i=0;i<val.length;i++){
if(val[i]!=0){
sum+=1;
}
}
return sum;
}
private static int[][] children(int[] p){
int pChildern=numChildren(p);
int[] d=new int[pChildern];
int[][] r=new int[pChildern][];
int c=0;
for(int j=0;j<p.length;j++){
if(p[j]!=0){
d[c]=j;
c++;
}
}
for(int i=0;i<pChildern;i++){
p[d[i]]--;
r[i]=p.clone();
p[d[i]]++;
}
return r;
}
}
My code does execute but doesn't produce correct result. It should print 6 but it prints 3.
Can any one suggest me what is wrong with this code?

// Returns size of subtree including the root
int getNumChilds(Node node) {
int count = 1;
for (Node child : node.getChildren()) {
count += getNumChilds(child);
}
return count;
}

I didn't really go into details, but this block looks weird:
int[][] ge=children(v);
for(int[] e:ge){
return 1+num(e);
}
System.out.print("this return should never execute");
return 0;
You want to sum up all its children here, but you return too early. It should be something like this:
int[][] ge=children(v);
int totChild = 0;
for(int[] e:ge){
totChild = totChild + num(e);
}
return totChild;

I think following code might be well suited to your needs.
{1, 0, 1, 0, 1} --> gives 7 (2 x 2 x 2 - 1)
{1, 1, 1, 1, 1} --> gives 31 (2 x 2 x 2 x 2 x 2 - 1)
{4, 4, 1, 1, 1} --> gives 199 (5 x 5 x 2 x 2 x 2 - 1)
-1 is to remove {0, 0, 0, 0, 0} from children.
public class Recursion {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
int[] c={4,4,1,1,1};
System.out.println(num(c, 0));
}
private static void print(int[] v) {
System.out.print("[");
for ( int i = 0; i < v.length; ++i ) {
System.out.print(v[i] + ",");
}
System.out.println("] ");
}
private static int num(int[] v, int k){
if(numChildren(v)==1){
return 1;
}
else{
int r = 1;
for ( int i = k; i < v.length; ++i ) {
if ( v[i] > 0) {
int o = v[i];
v[i] = o - 1;
print(v);
r += num(v, i);
v[i] = o;
}
}
return r;
}
}
private static int numChildren(int[] val){
int sum=0;
for(int i=0;i<val.length;i++){
if(val[i]!=0){
sum+=1;
}
}
return sum;
}
}

Related

recursively finding two elements with the smallest difference in an array

I'm trying to recursively find two elements in an array with the smallest difference (assume the array is already sorted in an increasing order).
I've been trying to get my code to just return the smallest sum, but something seems to be not working right with the recursion.
public class SmallestDiff {
public static void main (String [] args){
int [] x = {1,3,6,9,126};
System.out.println(smallestDiff(x,4));
}
public static int smallestDiff (int [] array, int index){
int result;
if (index>0){
int diff = Math.abs((array[index]-array[index-1]));
result = Math.min (diff, smallestDiff(array,index-1));
}
else {
return array[0];
}
return result;
}
}
Your mistake is
return array[0];
array[0] is not a difference between values so should not be returned. The simplest way to fix your program is to replace this line with
return array[1] - array[0];
Try this :
public class SmallestDiff {
public static void main(String[] args) {
int[] x = { 1, 3, 6, 9, 126 };
int result;
if (x.length < 2) {
result = x[0];
}
else{
result = smallestDiff(x, x.length-1);
}
System.out.println(result);
}
public static int smallestDiff(int[] array, int index) {
if (index == 0) {
return Integer.MAX_VALUE;
}
int diff = (array[index] - array[index - 1]);
return Math.min(diff, smallestDiff(array, index - 1));
}
}
This solution prints the first element in case there is only one element in the array. Otherwise, it will always result the smallest difference between two elements.
If your array is sorted no need for recursion.
The code below solves the problem with iteration.
public class SmallestDiff {
public static void main(String[] args) {
int[] x = {1, 3, 6, 9, 126};
System.out.println(smallestDiff(x));
}
public static int smallestDiff(int[] array) {
int result = Integer.MAX_VALUE;
for (int i = 0; i < array.length - 1; i++) {
int diff = Math.abs((array[i] - array[i + 1]));
if (diff < result) {
result = diff;
}
}
return result;
}
}

All possible permutations of a NxN matrix in Java

I want to generate all possible permutations of a matrix using recursion.
For example 2x2 matrix will have 24 possibilities.
1 2 1 2 1 3 1 4
3 4, 4 3, 2 4, 2 3....24 possibilities.
Here is my code. The logic looks fine but I could get only four different possibilities. I hope someone can help me out with this.
public class NewClass
{
public static int LENGTH=2,count=0;
public static int check_if_array_is_fully_filled(int[][] a)
{
for(int i=0;i<a.length;i++)
{
for(int j=0;j<a.length;j++)
{
if(a[i][j]==0)
{
return 0;
}
}
}
return 1;
}
public static int[][] initialize_all_zeros(int[][] a)
{
for(int i=0;i<a.length;i++)
{
for(int j=0;j<a.length;j++)
{
a[i][j]=0;
}
}
return a;
}
public static void display(int[][] a)
{
for(int i=0;i<a.length;i++)
{
for(int j=0;j<a.length;j++)
{
System.out.print(a[i][j] + " ");
}
System.out.println();
}
System.out.println("********");
count++;
}
public static void generate(int[][] a, int value_to_enter, int done)
{
if(done == 0)
{
for(int i=0;i<a.length;i++)
{
for(int j=0;j<a.length;j++)
{
if(a[i][j] == 0)
{
a[i][j]=value_to_enter;
value_to_enter++;
int v = check_if_array_is_fully_filled(a);
if(v == 1)
{
done = 1;
}
else
{
generate(a,value_to_enter,0);
}
}
}
}
}
if(done == 1)
{
display(a);
}
}
public static void main(String[] agrs)
{
int[][] a;
for(int i=0;i<LENGTH;i++)
{
for(int j=0;j<LENGTH;j++)
{
a = new int[LENGTH][LENGTH];
a = initialize_all_zeros(a);
a[i][j]=1;
generate(a,2,0);
}
}
System.out.println(count);
}
}
Here is the recursive function for a 1d array using the same logic as you did. The 2d is more or less the same thing.
private static void generate(int[] values, int currentValue) {
if (currentValue == values.length + 1) {
System.out.println(Arrays.toString(values));
return;
}
for (int i = 0; i < values.length; i++) {
if (values[i] == 0) {
values[i] = currentValue;
generate(values, currentValue + 1);
values[i] = 0;
}
}
}
Call like so:
generate(new int[3], 1);
Outputs
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[3, 1, 2]
[2, 3, 1]
[3, 2, 1]
Which should be encapsulated in a
public static void generate(int size) {
generate(new int[size], 1);
}
My pseudo approach would be:
convert matrix to list
permute list
for each permutation of the list, convert list back to matrix.
You have not mentioned if all the elements in your matrix are unique. If they are not, then you need to remove duplicate lists from your permutation as well (need to filter after 2, before 3.
permute list:
The easiest way to understand this is by recursion.
The base step is when you have two numbers, the permutations are easy. it is (a,b) and (b,a)
To add a third element, you will add the element to all positions
e.g. permute(c,{(a,b), (b,a)}) = { (c,a,b), (a,c,b),(a,b,c),
(c,b,a), (b,c,a), (b,a,c) }
so, you recursion will be permute(a,permutedlist)
for each b in permutedlist, add a to all possible positions in the list.

Using Java check n value is appears n time and the number is in consecutive location in an given array

Question: Define an array to be packed if all its values are positive, each value n appears n times and all equal values are in consecutive locations. So for example, {2, 2, 3, 3, 3} is packed because 2 appears twice and 3 appears three times. But {2, 3, 2, 3, 3} is not packed because the 2s are not in consecutive locations. And {2, 2, 2, 3, 3, 3} is not packed because 2 appears three times.
Write a method named isPacked that returns 1 if its array argument is packed, otherwise it returns 0. You may assume that the array is not null
If you are programming in Java or C#, the function signature is
int isPacked(int[ ] a)
public class isPackd{
public static void main(String[] args){
int result=isPacked(new int[ ] {2, 2, 1});
System.out.println("Return: " + result);
result=isPacked(new int[ ] {7, 7, 7, 7, 1, 7, 7, 7});
System.out.println("Return: " + result);
}//main()
public static int isPacked(int[ ] a){
for (int i=0; i<a.length; i++) {
int chkHowManyTimes=howManyTimes(a, a.length, a[i]);
if (chkHowManyTimes !=a[i]) {
return 0;
} // end of if
} // end of for
if (isConsecutive(a)==0) {
return 0;
} // end of if
return 1;
}//isPacked()
public static int howManyTimes(int[] array, int length, int findNumber){
int count=0;
for (int i=0; i<length; i++) {
if (array[i]==findNumber) {
count +=1;
} // end of if
} // end of for
//System.out.println(count);
return count;
}//howMany..()
public static int isConsecutive(int[] a){
//
//need help here to write code for this section
//
return 1;
}//isCon..()
}//class
I need help to check whether the number is in consecutive location or not.
And then,here is the full code below.
So, is there anything just feel free to ask here.
public class Consecutive
{
/***************************************************************************/
Author :- ShihabSoft
/***************************************************************************/
public static void main(String[] someArgs)
{
int[] args=new int[someArgs.length];
for(int i=0;i<someArgs.length;i++)
args[i]=Integer.parseInt(someArgs[i]);
int swit=checkArrConsecutive(args);
if(swit==0 || swit==1)
System.out.println("All "+args.length+" values appeared accordingly in the array");
switch(swit)
{
case 0:
System.out.println("Array is not well packed.");
break;
case 1:
System.out.println("Array is well packed");
}
}
//As per your needs we need two functions
static int checkArrConsecutive(int[] args)
{
int curr=0,temp=0;
if(args!=null)
{
int numIndex=0;
for(int i=0;i<args.length;i++)
{
curr=args[i];
temp=0;
if(checkNoccursNtime(args,curr)==0)
{
System.out.println("Sorry the number :- "+curr+" at index '"+i+"' repeats more or less than '"+curr+"' times");
return 2;
}
for(int j=numIndex;j<args.length;j++)
{
if(temp==curr)
break;
if(args[j]!=curr)
{
return 0;
}
else
temp++;
}
if(curr!=(args.length!=(i+1) ? args[i+1] : args[i]))
numIndex=i+1;
}
return 1;
}
return 0;
}
static int checkNoccursNtime(int[] args,int n)
{
if(args!=null)
{
int curr=0,temp=0;
temp=0;
curr=n;
for(int j=0;j<args.length;j++)
{
if(args[j]==curr && temp != curr)
temp++ ;
else if(args[j]==curr)
return 0;
}
return temp==curr ? 1 : 0;
}
return 0;
}
}
Just compile the above code and run passing values like this.
java Consecutive 5 5 5 5 5 1 2 2 3 3 3
public class Packed {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = { 7, 7, 7, 7, 7,7, 7 };
int tt = isPacked(a);
System.out.println(tt);
}
private static int isPacked(int[] a) {
int n;
int count = 0;
int k = 0;
int initialindex;
int finalindex = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] < 0) {
return 0;
}
n = a[i];
k = 0;
initialindex = i;
for (int j = 0; j < a.length; j++) {
k++;
if (n == a[j]) {
i++;
finalindex = k;
count++;
}
}
if (n != count || (finalindex - initialindex) != count) {
return 0;
}
i--;
count = 0;
}
return 1;
}
}

recursive code to non recursive with loops

Hello I want this code to non recursive how I can do it?
public class test {
public static void main(String[] args) {
int[] array = new int[]{0, 1, 2,3};
int size = 2;
int[] tmp = new int[size];
//Arrays.fill(tmp, -1);
generateCombinations(array, 0, 0, tmp);
}
private static void generateCombinations(int[] array, int start, int depth, int[] tmp) {
if (depth == tmp.length) {
for (int j = 0; j < depth; j++) {
System.out.print(array[tmp[j]]);
} System.out.println();
return;
}
for (int i = start; i < array.length; i++) {
tmp[depth] = i;
generateCombinations(array, i + 1, depth + 1, tmp);
}
}
}
It generates all the combinations from specific numbers.
Every recursion could be rewritten to iteration and vice a versa. You just have to follow a common algorithm:
Replace Recursion with Iteration
Replace Iteration with Recursion
Determine the base case of the Recursion. Base case, when reached, causes Recursion to end. Every Recursion must have a defined base
case. In addition, each recursive call must make a progress towards
the base case (otherwise recursive calls would be performed
infinitely). In our example the base case is n == 0.
Implement a loop that will iterate until the base case is reached.
Make a progress towards the base case. Send the new arguments to the top of the loop instead to the recursive method.
Behind this lies the concept of maintaining invariant condition.
Try this:
public class Test {
private final int[] array;
private final int[] tmp;
private Test(int[] array, int size) {
tmp = new int[size];
this.array = array;
}
public static void main(String[] args) {
Test t = new Test(new int[] {0, 1, 2, 3}, 2);
t.generateCombinations();
}
/**
* Print the selection.
*/
private void print() {
for (int i : tmp) {
System.out.print(array[i]);
}
System.out.println();
}
/**
* Set values in tmp for indices startIndex, ..., (tmp.length-1)
* to startValue, ..., (startValue-startIndex + tmp.length-1)
* #param startIndex
* #param startValue
*/
private void initMin(int startIndex, int startValue) {
final int offset = startValue - startIndex;
for (int i = startIndex; i < tmp.length; i++) {
tmp[i] = i+offset;
}
}
private void generateCombinations() {
if (tmp.length == 0) return;
initMin(0, 0);
print();
final int maxIndex = tmp.length-1;
int index = maxIndex;
final int z = array.length-tmp.length;
while (index >= 0) {
if (tmp[index] == index+z) {
index--;
} else {
if (tmp[index]== index+z-1) {
// only value at index changes
tmp[index]++;
index--;
} else {
initMin(index, tmp[index]+1);
index = maxIndex;
}
print();
}
}
}
}
The algorithm is based on the following observation:
tmp[i] must be at most (i+array.length-tmp.length)
The algorithm always always adds 1 at the last position, where this is still possible and sets the values at the following positions to the smallest possible values.

Grid walking algorithm code correction

Grid Walking (Score 50 points):
You are situated in an N dimensional grid at position (x_1,x2,...,x_N). The dimensions of the grid are (D_1,D_2,...D_N). In one step, you can walk one step ahead or behind in any one of the N dimensions. (So there are always 2N possible different moves). In how many ways can you take M steps such that you do not leave the grid at any point? You leave the grid if you for any x_i, either x_i <= 0 or x_i > D_i.
Input:
The first line contains the number of test cases T. T test cases follow. For each test case, the first line contains N and M, the second line contains x_1,x_2...,x_N and the 3rd line contains D_1,D_2,...,D_N.
So, in the above solution I'm trying to take one dimensional array.
The website claims 38753340 to be the answer, but I'm not getting it.
public class GridWalking {
/**
* #param args
*/
public static void main(String[] args) {
try {
long arr[] = new long[78];
long pos = 44;
long totake = 287;
/*
* Double arr[] = new Double[3]; Double pos = 0; Double totake = 5;
*/
Double val = calculate(arr, pos, totake);
System.out.println(val % 1000000007);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public static HashMap<String, Double> calculated = new HashMap<String, Double>();
private static Double calculate(long[] arr, long pos, long totake) {
if (calculated.containsKey(pos + "" + totake)) {
return calculated.get(pos + "" + totake);
}
if (0 == totake) {
calculated.put(pos + "" + totake, new Double(1));
return new Double(1);
}
if (pos == arr.length - 1) {
Double b = calculate(arr, pos - 1, totake - 1);
Double ret = b;
calculated.put(pos + "" + totake, new Double(ret));
return ret;
}
if (pos == 0) {
Double b = calculate(arr, pos + 1, totake - 1);
Double ret = b;
calculated.put(pos + "" + totake, new Double(ret));
return ret;
}
Double a = calculate(arr, pos + 1, totake - 1);
Double b = calculate(arr, pos - 1, totake - 1);
Double ret = (a + b);
calculated.put(pos + "" + totake, ret);
return ret;
}
}
You need to change key values as for pos + "_" + totake.
I have rewritten it but I'm not sure it working or not. It takes too much time to complete if ever.
public class GridWalking {
static long arr_length = 78;
static long pos = 44;
static long totake = 287;
static long count = 0;
/**
* #param args
*/
public static void main(String[] args) {
try {
calculate(pos, totake);
System.out.println(count % 1000000007);
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
private static void calculate(long pos, long totake) {
if (pos < 0 || pos > arr_length - 1)
return;
if (0 == totake) {
count++;
return;
}
calculate(pos + 1, totake - 1);
calculate(pos - 1, totake - 1);
}
}
I have tried solving that Grid walking problem in Hackerrank. this is the code that had worked(in ecclipse atleast). but i donno why it does not match with given answers. Nut i think you can get the idea from it. Since it does not use recursion, no problem with execution time..
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
static int count=0;
public static void main(String[] args) throws FileNotFoundException {
String filename = "src/testcases.txt";//testcases is just a file containing input
File file = new File(filename);
Scanner in = new Scanner(file);
//in.useDelimiter("[^0-9]+");
//-----------------------------------------------------------------
int T=in.nextInt();
for(int t=0;t<1;t++){
int N=in.nextInt();
int M=in.nextInt();System.out.println("M="+M);
int[] X=new int[N];
long max=1000000007;
int[] D=new int[N];
for(int i=0;i<N;i++) X[i]=in.nextInt();
for(int i=0;i<N;i++) D[i]=in.nextInt();
int Dmax=D[0];
int Dtotal=1;
for(int i=0;i<N;i++) if(Dmax<D[i]) Dmax=D[i];
for(int i=0;i<N;i++) X[i]--;
for(int i=0;i<N;i++) Dtotal*=D[i];//total number of fields
long[] mainarray= new long[Dtotal];
long[] mainarraynext=new long[Dtotal];
int[][] ways=new int[N][Dmax];
set( X, mainarray,D, 1);
int temp[]=new int[N];
for(int h=0;h<10;h++){
for(int j=0;j<Dtotal;j++){
mainarraynext[j]=getsum(inverse(j,D),mainarray, D );
}
for(int j=0;j<Dtotal;j++){
mainarray[j]=mainarraynext[j];
mainarray[j]%=max;
}
System.out.println(Arrays.toString(mainarray));
}
long finalsum=0;
for(int j=0;j<Dtotal;j++){
finalsum+=mainarray[j];
//System.out.println(finalsum);
}
System.out.println(finalsum);
//System.out.println(Arrays.toString(inverse(44,D)));
}
}
public static long get(int[] x, long[] mainarray, int[] D){
for(int i=0;i<x.length;i++){
if(x[i]>=D[i]) return 0;
if(x[i]<0) return 0;
}
int index=0;
for(int i=0;i<D.length;i++){
index=(index*D[i])+x[i];
}
return mainarray[index];
}
public static int[] inverse(int index,int[] D){
int[] temp=new int[D.length];
for(int i=D.length-1;i>=0;i--){
temp[i]=index%D[i];
index=index/D[i];
}
return temp;
}
public static void set(int[] x, long[] mainarray, int[] D, int value){
int index=0;
for(int i=0;i<D.length;i++){
index=(index*D[i])+x[i];
}
mainarray[index]=value;
}
public static long getsum(int[] x,long[] mainarray, int[] D ){
int[] temp=new int[x.length];
long sum=0;
//for 2n different sides
for(int j=0;j<x.length;j++){//sum in each side
temp[j]=x[j];
}
for(int j=0;j<x.length;j++){//sum in each side
temp[j]--;
sum+=get(temp, mainarray, D);
temp[j]+=2;
sum+=get(temp, mainarray, D);
temp[j]--;
}
return sum;
}
}
Here's a Java solution I've built for the original hackerrank problem. For big grids runs forever. Probably some smart math is needed.
long compute(int N, int M, int[] positions, int[] dimensions) {
if (M == 0) {
return 1;
}
long sum = 0;
for (int i = 0; i < N; i++) {
if (positions[i] < dimensions[i]) {
positions[i]++;
sum += compute(N, M - 1, positions, dimensions);
positions[i]--;
}
if (positions[i] > 1) {
positions[i]--;
sum += compute(N, M - 1, positions, dimensions);
positions[i]++;
}
}
return sum % 1000000007;
}

Categories