Array of binomial coefficients - java

So, I have implemented the binomial coefficient
public static int binomial(int n, int k) {
if (k == 0)
return 1;
else if (k > n - k)
return binomial(n, n - k);
else
return binomial(n - 1, k - 1) * n / k;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Insert n: ");
int n = scan.nextInt();
System.out.println("Insert k: ");
int k = scan.nextInt();
System.out.println("Result: " + binomial(n, k));
}
And it works, but where I'm stuck is just that I need to add the coefficient array for two given numbers. So If n is 5 and k is 3. The coefficient array will display: 1 5 10 10. Any ideas?

Don't call recursive code in a for loop. That adds a stupid amount of redundancy.
Pass the array as a parameter to the recursive function from main. Arrays are passed by reference in java.
public static int binomial(int n, int k, int[] coefficient) {
int ret;
if (k == 0) {
ret = 1;
} else if (k > n - k) {
ret = binomial(n, n - k, coefficient);
} else {
ret = binomial(n - 1, k - 1, coefficient) * n / k;
}
coefficient[k] = ret;
return ret;
}

All you need to do is put your expression in a loop and hold n constant.
for (int k = 0; k <= n; k++) {
System.out.print(binomial(n, k) + " ");
}
You can store these values in an array if you like. There is no need to make your method any more complicated.
If want to put it in an array, here is one easy way to do it.
int coefs[] = IntStream.rangeClosed(0, n).map(k -> binomial(n, k)).toArray();
coefs[] = [1, 5, 10, 10, 5, 1]

You can create two iterative methods: one returns a 2d array containing Pascal's triangle, and the second returns the base of that triangle. It is more useful for clarity.
Output:
Insert n:
6
Pascal's triangle:
[1, 1, 1, 1, 1, 1]
[1, 2, 3, 4, 5]
[1, 3, 6, 10]
[1, 4, 10]
[1, 5]
[1]
Binomial coefficients:
[1, 5, 10, 10, 5, 1]
Code:
public static int[][] binomialTriangle(int n) {
// an array of 'n' rows
int[][] arr = new int[n][];
// iterate over the rows of the array
IntStream.range(0, n).forEach(i -> {
// a row of 'n-i' elements
arr[i] = new int[n - i];
// iterate over the columns of the array
IntStream.range(0, n - i).forEach(j -> {
if (i == 0 || j == 0)
// first row and column
// are filled with ones
arr[i][j] = 1;
else
// all other elements are the sum of the
// previous element in the row and column
arr[i][j] = arr[i][j - 1] + arr[i - 1][j];
});
});
return arr;
}
public static int[] binomialCoefficient(int[][] triangle) {
return Arrays.stream(triangle)
// the last element in the row
.mapToInt(row -> row[row.length - 1])
.toArray();
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Insert n:");
int n = scan.nextInt();
System.out.println("Pascal's triangle:");
int[][] arr = binomialTriangle(n);
Arrays.stream(arr).map(Arrays::toString).forEach(System.out::println);
int[] base = binomialCoefficient(arr);
System.out.println("Binomial coefficients:");
System.out.println(Arrays.toString(base));
}
See also: Convert negative index to positive index in an array (Trinomial Triangle)

Related

Optimize FOR loop for adding array elements to set

I have an array Ar of size N(Ar[N]). I have to divide the Ar[N] into sub arrays of size K and then add them to a Set S.
For example if Ar[5] = {1,2,3,4,5} and K = 3
then,
Sub arrays will be {1,2,3},{2,3,4},{3,4,5}
Now I have to add these sub arrays to the Set and continue my computations.
Here is my code :
int max = 0;
for(int j=0;j<=N-k;j++){
Set<Integer> set = new HashSet<>();
for(int l=j;l<j+K;l++){
set.add(Ar[l]);
}
if(set.size >= max) max = set.size;
}
System.out.println(max);
Is there any way that I can get rid of the nested for loop as in worst case N can be 1000000.
NOTE : The set should only contain unique values.
Hope I am clear.
Maintain a window of i-k-1 to i of set when traversing the array. You can use HashMap to count the frequency of value and remove it when the frequency is zero. And update max value of set then you will get max set size of each subarray's set.
int[] arr = {1,2,1,4,1};
int k = 3;
int max = 0;
Map<Integer, Integer> map = new HashMap<>();
Set<Integer> set = new HashSet<>();
for (int i = 0; i < arr.length; i++) {
set.add(arr[i]);
map.merge(arr[i], 1, Integer::sum);
if(i >= k) {
map.merge(arr[i-k], -1, Integer::sum);
if(map.get(arr[i-k]) == 0) {
set.remove(arr[i-k]);
}
}
if(set.size() >= max) {
max = set.size();
}
}
Alternative solution. Try to use "subList()" described in: How to use subList()
See example below:
public static void main(String[] args) {
int startNumber = 1;
int endNumber = 5;
List<Integer> mainList = new ArrayList<>();
for (int i = startNumber; i <= endNumber; i++) {
mainList.add(i);
}
// See mainList:
System.out.println(mainList); // output: [1, 2, 3, 4, 5]
int sizeOfEachSubList = 3;
int loopStopPoint = mainList.size() - sizeOfEachSubList;
List<List<Integer>> listOfLists = new ArrayList<>();
for (int i = 0; i <= loopStopPoint; i++) {
List<Integer> subList = mainList.subList(i, sizeOfEachSubList + i);
listOfLists.add(subList);
}
//See all lists:
System.out.println(listOfLists); // output: [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
}
If actual task is to define the maximum size of a subset after dividing into K elements, it can be implemented this way:
public static long findMaxSize(int[] arr, int k) {
return IntStream.rangeClosed(0, arr.length - k)
.mapToLong(i ->
Arrays.stream(Arrays.copyOfRange(arr, i, i + k))
.distinct().count())
.max().getAsLong();
}
Also, splitting of the input array by K elements into subsets may be implemented this way:
public static Set<Set<Integer>> splitIntoSubsetsByK(int[] arr, int k) {
return IntStream.rangeClosed(0, arr.length - k)
.mapToObj(i -> Arrays.stream(Arrays.copyOfRange(arr, i, i + k))
.boxed().collect(Collectors.toSet()))
.collect(Collectors.toCollection(LinkedHashSet::new));
}
Test and output:
int[] arr = {1, 2, 2, 2, 1};
int k = 3;
Set<Set<Integer>> result = splitIntoSubsetsByK(arr, k);
result.forEach(System.out::println);
System.out.println(findMaxSize(arr, k));
[1, 2]
[2]
2

How to find missing Smallest Positive Integer using the lamda expresion in java

that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
import java.util.*;
class Main {
/* Utility function that puts all non-positive
(0 and negative) numbers on left side of
arr[] and return count of such numbers */
static int segregate(int arr[], int size)
{
int j = 0, i;
for (i = 0; i < size; i++) {
if (arr[i] <= 0) {
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
// increment count of non-positive
// integers
j++;
}
}
return j;
}
/* Find the smallest positive missing
number in an array that contains
all positive integers */
static int findMissingPositive(int arr[], int size)
{
int i;
// Mark arr[i] as visited by making
// arr[arr[i] - 1] negative. Note that
// 1 is subtracted because index start
// from 0 and positive numbers start from 1
for (i = 0; i < size; i++) {
int x = Math.abs(arr[i]);
if (x - 1 < size && arr[x - 1] > 0)
arr[x - 1] = -arr[x - 1];
}
// Return the first index value at which
// is positive
for (i = 0; i < size; i++)
if (arr[i] > 0)
return i + 1; // 1 is added becuase indexes
// start from 0
return size + 1;
}
/* Find the smallest positive missing
number in an array that contains
both positive and negative integers */
static int findMissing(int arr[], int size)
{
// First separate positive and
// negative numbers
int shift = segregate(arr, size);
int arr2[] = new int[size - shift];
int j = 0;
for (int i = shift; i < size; i++) {
arr2[j] = arr[i];
j++;
}
// Shift the array and call
// findMissingPositive for
// positive part
return findMissingPositive(arr2, j);
}
// main function
public static void main(String[] args)
{
int arr[] = { 0, 10, 2, -10, -20 };
int arr_size = arr.length;
int missing = findMissing(arr, arr_size);
System.out.println("The smallest positive missing number is " + missing);
}
}
}
If you need to use stream, the more straightfoward, but not optimal way to do it is to create an infinite stream, starting at 1 and return the first that is not in arr:
int[] arr = { 1, 3, 6, 4, 1, 2 };
Set<Integer> arrSet = Arrays.stream(arr).boxed().collect(Collectors.toSet());
Optional<Integer> found = IntStream.iterate(1, o -> o + 1).boxed()
.filter(value -> !arrSet.contains(value))
.findFirst();
found.ifPresent(System.out::println);
Output
5
As pointed out this is very inefficient, but in terms of computational complexity I believe is optimal, at least for the worst case i.e. the one you have to look at all the elements.
Below you can find the missing positive integer using Streams -
int ar[] = { 0, 10, 2, -10, -20 };
int max = Arrays.stream(ar).max().getAsInt();
System.err.println("maxvalue "+max);
int val = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i))
.findFirst().getAsInt();
System.out.println(val);
int[] val1 = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(val1).forEach(System.out::println);
int[] valEven = IntStream.range(1, max).filter(i->Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven).forEach(System.out::println);
int[] valOdd = IntStream.range(1, max).filter(i->!Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd).forEach(System.out::println);
int[] valOdd1 = IntStream.range(1, max).filter(i->Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd1).forEach(System.out::println);
int[] valEven1 = IntStream.range(1, max).filter(i->!Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven1).forEach(System.out::println);
You can also do a mix of stream and primitive int loop:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numberSet1 = {1, 3, 6, 4, 1, 2};
int[] numberSet2 = {-1, -3};
int[] numberSet3 = {1, 2, 3};
System.out.println(calcularPrimero(numberSet1));
System.out.println(calcularPrimero(numberSet2));
System.out.println(calcularPrimero(numberSet3));
}
public static int calcularPrimero (int[] A) {
//IntStream intStream = Arrays.stream(A).filter(x -> x >= 0).distinct().sorted();
int[] B = Arrays.stream(A).filter(x -> x > 0).distinct().sorted().toArray();
for (int i = 0, index = 1; i < B.length; i++, index++) {
if (index != B[i]) {
return index;
}
}
return B.length + 1;
}
}

How to find minimum in subarray in java

I had an exam which I failed to display it.
Kindly help how to achieve this
Given an array A[] of size N and an integer k. Task is to print the minimum element for each subarray of size k.
For Each valid index i(0<=i <=N -K) Have to print min(A[i],A[i+1],A[i+2]...A[i+k]).
Input format:
The first line will coontains two integers N and k.
The second line contain N intgers denoting the elements of Array A[]
Constraints:
1 <=N <=10^5
1<=K <= N
1<=A[i] <=10^6
Output Format
print the minimum elements for each subarray of size k separated by space.
input:
5 2
10 0 3 2 5
output:
0 0 2 2
But what I tried is find maximum element:
I know this is wrong. But I know only this.
public static int maxSum(int arr[], int n, int k)
{
// k must be greater
if (n < k)
{
System.out.println("Invalid");
return -1;
}
// Compute sum of first window of size k
int res = 0;
for (int i=0; i<k; i++)
res += arr[i];
// Compute sums of remaining windows by
// removing first element of previous
// window and adding last element of
// current window.
int curr_sum = res;
for (int i=k; i<n; i++)
{
curr_sum += arr[i] - arr[i-k];
res = Math.max(res, curr_sum);
}
return res;
}
/* Driver program to test above function */
public static void main(String[] args)
{
int arr[] = {5,2,10,0,3,2,5};
int k = 7;
int n = arr.length;
System.out.println(maxSum(arr, n, k));
}
}
This is a super-straightforward solution I wrote in about 5 minutes.
Note I don't perform the input, the n, k, array values are just hardcoded in main method.
package stackoverflow;
public class MinimumSubArray {
public static void main(String[] args) {
solve(5, 2, new int[]{ 10, 0, 3, 2, 5 }); // expect 0 0 2 2
solve(5, 2, new int[]{ 10, 0, 3, 2, 1 }); // expect 0 0 2 1
solve(1, 1, new int[]{ 6 }); // expect 6
solve(3, 3, new int[]{ 3, 2, 1 }); // expect 1
solve(3, 1, new int[]{ 3, 2, 1 }); // expect 3 2 1
}
private static void solve(final int n, final int k, final int[] array) {
if (n != array.length)
throw new IllegalArgumentException( String.format("Array length must be %d.", n) );
if (k > n)
throw new IllegalArgumentException( String.format("K = %d is bigger than n = %d.", k, n) );
int currentStartIndex = 0;
while (currentStartIndex <= (n - k)) {
int min = array[currentStartIndex];
for (int i = currentStartIndex + 1; i < currentStartIndex + k; i++) {
if (array[i] < min) {
min = array[i];
}
}
System.out.printf("%d ", min); // print minimum of the current sub-array
currentStartIndex++;
}
System.out.println();
}
}

How to copy the leftmost n elements in one array into the rightmost n position in another array in reverse order

So I'm suck on trying to come up with a function that takes in a (int[] X, int n, int[] Y) as parameters and copies the leftmost n elements in X[] into the rightmost n positions in Y[] in reverse order.
so far, I have created a separate function that that prints out the reversal of the leftmost n element in A.
public static void reverseArray1(int[] A, int n) {
if(n > 0) {
System.out.print(A[n-1] + " ");
reverseArray1(A, n-1);
}
}
This is my program at the moment:
class Recursion {
static void reverseArray1(int[] X, int n, int[] Y) {
//This is where I'm stuck
}
public static void main(String[] args) {
int[] A = {-1, 2, 3, 12, 9, 2, -5, -2, 8, 5, 7};
int[] B = new int[A.length];
for(int x: A) System.out.print(x+" ");
System.out.println();
reverseArray1(A, A.length, B);
for(int x: B) System.out.print(x+" ");
System.out.println();
}
}
This should be pretty simple using recursion:
void copyNFromLeft(int[] left, int n, int[] right) {
if (n < 1)
return;
right[right.length - n] = left[n - 1];
copyNFromLeft(left, n - 1, right);
}
You could add some additional checks for indexOutOfBounds cases, e.g. when n > right.length (or left.length). Basically, something like this:
if (n > left.length || n > right.length)
n = Math.min(left.length, right.length);

Print out all permutations of an Array [duplicate]

This question already has answers here:
Permutation of array
(13 answers)
Closed 7 years ago.
I am working on a program, and I have a function that swaps the positions in an Array of length that is input by a user. However, I am trying to figure out how to print out this function call N! times, which would list all the permutations in the function.
My code for the permutation function is:
static void nextPerm(int[] A){
for( int i = (n-1); i > 0; i-- ){
if( A[i] < A[i+1] ){
A[i] = pivot;
continue;
}
if( A[i] >= A[i+1] ){
reverseArray(A);
return;
}
}
for( int i = n; i > 0; i--){
if( A[i] > pivot ){
A[i] = successor;
continue;
}
}
Swap(pivot, successor);
int[] B = new int[pivot+1];
reverseArray(B);
return;
}
Should I write a loop in function main, that will print this out n! times?
Creating (or printing) the permutations of an array is much easier done as a combination of recursively and iteratively than purely iteratively. There are surely iterative ways to do it, but it is particularly simple with a combination. Specifically, note that there are by definition N! permutations of a length N array - N choices for the first slot, N-1 choices for the 2nd, etc etc. So, we can break an algorithm down into two steps for each index i in the array.
Select an element in the sub-array arr[i....end] to be the ith element of the array. Swap that element with the element currently at arr[i].
Recursively permute arr[i+1...end].
We note that this will run in O(N!), as on the 1st call N sub calls will be made, each of which will make N-1 sub calls, etc etc. Moreover, every element will end up being in every position, and so long as only swaps are made no element will ever be duplicated.
public static void permute(int[] arr){
permuteHelper(arr, 0);
}
private static void permuteHelper(int[] arr, int index){
if(index >= arr.length - 1){ //If we are at the last element - nothing left to permute
//System.out.println(Arrays.toString(arr));
//Print the array
System.out.print("[");
for(int i = 0; i < arr.length - 1; i++){
System.out.print(arr[i] + ", ");
}
if(arr.length > 0)
System.out.print(arr[arr.length - 1]);
System.out.println("]");
return;
}
for(int i = index; i < arr.length; i++){ //For each index in the sub array arr[index...end]
//Swap the elements at indices index and i
int t = arr[index];
arr[index] = arr[i];
arr[i] = t;
//Recurse on the sub array arr[index+1...end]
permuteHelper(arr, index+1);
//Swap the elements back
t = arr[index];
arr[index] = arr[i];
arr[i] = t;
}
}
Sample input, output:
public static void main(String[] args) {
permute(new int[]{1,2,3,4});
}
[1, 2, 3, 4]
[1, 2, 4, 3]
[1, 3, 2, 4]
[1, 3, 4, 2]
[1, 4, 3, 2]
[1, 4, 2, 3]
[2, 1, 3, 4]
[2, 1, 4, 3]
[2, 3, 1, 4]
[2, 3, 4, 1]
[2, 4, 3, 1]
[2, 4, 1, 3]
[3, 2, 1, 4]
[3, 2, 4, 1]
[3, 1, 2, 4]
[3, 1, 4, 2]
[3, 4, 1, 2]
[3, 4, 2, 1]
[4, 2, 3, 1]
[4, 2, 1, 3]
[4, 3, 2, 1]
[4, 3, 1, 2]
[4, 1, 3, 2]
[4, 1, 2, 3]
I have followed this method most of the time .. (it's given by the Robert Sedgewick and Kevin Wayne. ).
public class Permutations {
// print N! permutation of the characters of the string s (in order)
public static void perm1(String s) { perm1("", s); }
private static void perm1(String prefix, String s) {
int N = s.length();
if (N == 0) System.out.println(prefix);
else {
for (int i = 0; i < N; i++)
perm1(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, N));
}
}
// print N! permutation of the elements of array a (not in order)
public static void perm2(String s) {
int N = s.length();
char[] a = new char[N];
for (int i = 0; i < N; i++)
a[i] = s.charAt(i);
perm2(a, N);
}
private static void perm2(char[] a, int n) {
if (n == 1) {
System.out.println(a);
return;
}
for (int i = 0; i < n; i++) {
swap(a, i, n-1);
perm2(a, n-1);
swap(a, i, n-1);
}
}
// swap the characters at indices i and j
private static void swap(char[] a, int i, int j) {
char c;
c = a[i]; a[i] = a[j]; a[j] = c;
}
However There is also an easier way to do this. May be you can work also around this
class PermutingArray {
static void permutingArray(java.util.List<Integer> arrayList, int element) {
for (int i = element; i < arrayList.size(); i++) {
java.util.Collections.swap(arrayList, i, element);
permutingArray(arrayList, element + 1);
java.util.Collections.swap(arrayList, element, i);
}
if (element == arrayList.size() - 1) {
System.out.println(java.util.Arrays.toString(arrayList.toArray()));
}
}
public static void main(String[] args) {
PermutingArray
.permutingArray(java.util.Arrays.asList(9, 8, 7, 6, 4), 0);
}
}
Working Example here ..
IDeone Link
The trick is to return a special value (false in the code below) from nextPerm when it was the last permutation (i.e. when array become sorted in descending order):
import java.util.*;
public class Main {
public static boolean nextPerm(List<Integer> a) {
int i = a.size() - 2;
while (i >= 0 && a.get(i) >= a.get(i + 1))
i--;
if (i < 0)
return false;
int j = a.size() - 1;
while (a.get(i) >= a.get(j))
j--;
Collections.swap(a, i, j);
Collections.reverse(a.subList(i + 1, a.size()));
return true;
}
...
Then you can use the loop (note that the array required be sorted in ascending order initially):
...
public static void main(String[] args) {
List<Integer> a = Arrays.asList(new Integer[] {1, 2, 3, 4});
do {
System.out.println(a);
} while (nextPerm(a));
}
}
You can try this code here: http://ideone.com/URDFsc

Categories