Print out all permutations of an Array [duplicate] - java

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

Related

how to write a method to reverse a 2D array

I got this question to solve
Write a method that takes a two-dimensional array of type integer as a parameter and return
the inverse of the array (the rows become the columns and vice versa).
that is what I did through searching, but it shows a bunch of errors
public static class inverse{
public static int[][] arrayInverse(int[][] A){
int[][] B = new int[3][3];
for(int i=0; i<B.length/2;i++){
for (int j=0; j<B[i].length/2;j++) {
int swap = B[i][j];
B[B.length - i - 1] = swap;
}
}
return swap;
}
}
}
First, as mentioned in the comments, the task is to transpose the input array the rows become the columns and vice versa
If the input 2D array is square (the number of the rows is the same as the number of columns), the most efficient way would be to swap the elements below and over the main diagonal: a[i][j] ⇄ a[j][i] without using extra array:
public static int[][] transposeSquare(int[][] arr) {
for (int i = 0, n = arr.length; i < n; i++) {
// select the elements only above the main diagonal
for (int j = i + 1, m = arr[i].length; j < m; j++) {
int tmp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = tmp;
}
}
return arr;
}
However, in general case of a rectangular matrix it may be needed to create a new array/matrix of size M x N instead of N x M, and copy the values from the input in appropriate order (no swap is needed then):
public static int[][] transpose(int[][] arr) {
int[][] result = new int[arr[0].length][arr.length];
for (int i = 0, n = arr.length; i < n; i++) {
for (int j = 0, m = arr[i].length; j < m; j++) {
result[j][i] = arr[i][j];
}
}
return result;
}
You need to replace between columns and rows
public class inverse {
/**
* The entry point of application.
*
* #param args the input arguments
*/
public static void main(String[] args) {
int ints[][] = {{1, 2, 3},
{5, 6, 7},
{9, 10, 11},
{12, 13, 14}
};
print2D(ints);
System.out.println("\n");
print2D(arrayInverse(ints));
}
/**
* Array inverse int [ ] [ ].
*
* #param A the a
* #return the int [ ] [ ]
*/
public static int[][] arrayInverse(int[][] A) {
if (A.length == 0 || A[0].length == 0) {
System.out.println("A.length==0 || A[0].length==0");
return A;
}
int[][] B = new int[A[0].length][A.length];
for (int i = 0; i < B.length; i++) {
for (int j = 0; j < B[i].length; j++) {
B[i][j] = A[j][i];
}
}
return B;
}
/**
* Print 2 d.
*
* #param mat the mat
*/
public static void print2D(int mat[][]) {
// Loop through all rows
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat[i].length; j++) {
System.out.print(mat[i][j] + " ");
}
System.out.println(" ");
}
}
}
Output:
1 2 3
5 6 7
9 10 11
12 13 14
1 5 9 12
2 6 10 13
3 7 11 14
Here is a general solution. It will transpose any matrix, including a ragged one.
List<int[][]> demo = List.of(
new int[][] { { 1 }, { 2, 3, 4 }, { 5, 6 } },
new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } },
new int[][] { { 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 } });
for (int[][] arr : demo) {
System.out.println("Original");
for (int[] b : arr) {
System.out.println(Arrays.toString(b));
}
System.out.println("Transposed");
for (int[] b : transpose(arr)) {
System.out.println(Arrays.toString(b));
}
System.out.println();
}
prints
Original
[1]
[2, 3, 4]
[5, 6]
Transposed
[1, 2, 5]
[3, 6]
[4]
Original
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Transposed
[1, 4, 7]
[2, 5, 8]
[3, 6, 9]
Original
[1, 2, 3, 4, 5]
[6, 7, 8, 9, 10]
Transposed
[1, 6]
[2, 7]
[3, 8]
[4, 9]
[5, 10]
first, find the resulting number of rows, which is the maximum number of columns in the source matrix.
Then simply iterate thru the matrix, creating the new rows and copying the appropriate values of each column to their new row. Since the rows may be of different lengths, a check is made to ensure the value exists in the current row.
then copy that row of the proper length to the transposed row.
public static int[][] transpose(int[][] nums) {
int maxRows = nums[0].length;
for (int[] ar : nums) {
maxRows = Math.max(maxRows, ar.length);
}
int[][] trans = new int[maxRows][];
for (int r = 0; r < maxRows; r++) {
int[] row = new int[nums.length];
int cc = 0;
for (int c = 0; c < row.length; c++) {
if (r < nums[c].length) {
row[cc++] = nums[c][r];
}
}
trans[r] = Arrays.copyOf(row, cc);
}
return trans;
}
prints

Why does my binary search not work properly [duplicate]

This question already has answers here:
What is the difference between Linear search and Binary search?
(11 answers)
Closed 2 years ago.
Given an array of elements of length N, ranging from 0 to N – 1. All elements may not be present in the array. If element is not present then there will be -1 present in the array. Rearrange the array such that A[i] = i and if i is not present, display -1 at that place
So that is the question, but my binarySearch is not working, why?
for(int i = 0; i < size; i++) {
int res = i;
// System.out.println(Arrays.binarySearch(arr,res));
int result = Arrays.binarySearch(arr,res);
if(result == -1)
arr[i] = -1;
else {
arr[i] = i;
}
}
for(int i = 0; i < size; i++) {
System.out.print(arr[i]+" ");
}
Binary search works only with sorted arrays. Try using a different search algorithm
If you can use additional array, the solution may be as follows:
Create resulting array
Fill resulting array with -1
Iterate over input array and fill appropriate numbers in the resulting array.
// input array
int[] arr = {-1, 2, 3, 0};
// prepare new resulting array
int[] res = new int[arr.length];
// fill with -1
// Arrays.fill(res, -1); // use this shortcut if you're allowed to use library
for (int i = 0; i < res.length; i++) {
res[i] = -1;
}
// rearrange
for (int i = 0; i < arr.length; i++) {
if (arr[i] != -1) {
res[arr[i]] = arr[i];
}
}
System.out.println("input data: " + Arrays.toString(arr));
System.out.println("rearranged: " + Arrays.toString(res));
Output:
input data: [-1, 2, 3, 0]
rearranged: [0, -1, 2, 3]
Update
Recursive solution without using extra array:
public static void test() {
int[] arr = {-1, 4, 2, 0, 1, 3};
System.out.println("input data: " + Arrays.toString(arr));
// rearrange
for (int i = 0; i < arr.length; i++) {
if (arr[i] != -1 && arr[i] != i) {
swapAtIndex(arr, i);
}
}
System.out.println("rearranged: " + Arrays.toString(arr));
}
private static void swapAtIndex(int[] arr, int i) {
int t = arr[i];
if (t != -1 && t != i) {
int t2 = arr[t];
arr[t] = t;
arr[i] = t2;
if (t2 != -1) {
swapAtIndex(arr, i); // continue swapping at the same index
}
}
}
output:
input data: [-1, 4, 2, 0, 1, 3]
rearranged: [0, 1, 2, 3, 4, -1]
For the input array without -1, you'll get a sorted array after rearrangement:
input data: [5, 4, 2, 0, 1, 3]
rearranged: [0, 1, 2, 3, 4, 5]

Array of binomial coefficients

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)

Sorting a 2D array/Matrix by its diagonals

How could I rearrange a matrix by sorting every diagonal of a matrix?
[8, 4, 1 ] [4, 1, 1]
[4, 4, 1] --> [4, 8, 4]
[4, 8, 9] ‍‍‌‌‌‍‍‍‍‌‍‍‌‍‌‌‌‍‍ [4, 8, 9]
you can try something like this. However this is only for the forward diagonal.
public void diagonalArr(int[][] arr) {
int[] diagonalArr = new int[arr.length];
for(int i = 0;i<arr.length;i++) {
for(int j = 0;j<arr[0].length;j++) {
if(i == j) {
diagonalArr[i] = arr[i][j];
}
}
}
Arrays.sort(diagonalArr);
for(int i = 0;i<arr.length;i++) {
for(int j = 0;j<arr[0].length;j++) {
if(i == j) {
arr[i][j] = diagonalArr[i];
}
}
}
}

print all possible permutations of r elements in a given integer array of size n in Java [duplicate]

This question already has an answer here:
How do I calculate permutation? [closed]
(1 answer)
Closed 5 years ago.
Given an array of size n, generate and print all possible permutations of r elements in array.
For example, if n is 4, input array is [0, 1, 2, 3], and r is 3, then output should be
[0, 1, 2]
[0, 1, 3]
[0, 2, 1]
[0, 2, 3]
[0, 3, 1]
[0, 3, 2]
[1, 0, 2]
[1, 0, 3]
[1, 2, 0]
[1, 2, 3]
[1, 3, 0]
[1, 3, 2]
[2, 0, 1]
[2, 0, 3]
[2, 1, 0]
[2, 1, 3]
[2, 3, 0]
[2, 3, 1]
[3, 0, 1]
[3, 0, 2]
[3, 1, 0]
[3, 1, 2]
[3, 2, 0]
[3, 2, 1]
All elements in the input array are integers, from 0 to n-1. How can I use Java to print all possible permutations?
Important: the number of all elements in a single permutation is not always the size of original array. It's less or equal to the size of original array. Additionally, the order of elements in each permutation does matter.
I have written some code when n=4 and r=3. If n = 100 and r = 50, my code will be really ugly. Is there any smart way to do this when parameters are only n and r?
public static void main(String[] args) {
// original array
ArrayList < Integer > items = new ArrayList < > ();
// all permutations
ArrayList < ArrayList < Integer >> allPermutations = new ArrayList < ArrayList < Integer >> ();
// define the end item of the original array.
// this is n, suppose it's 4 now.
int endItem = 4;
for (int i = 0; i < endItem; i++) {
items.add(i);
}
// r means how many elements in each single permutation
// suppose it's 3 now, i have to write for-loop three times
// if r is 100, i have to write for-loop 100 times
// first of the "r"
for (int i = 0; i < items.size(); i++) {
// second of the "r"
for (int j = 0; j < items.size(); j++) {
// can't be identical to i
if (j == i)
continue;
// third of the "r"
for (int k = 0; k < items.size(); k++) {
// can't be identical to i or j
if (k == i || k == j)
continue;
// a single permutation
ArrayList < Integer > singlePermutation = new ArrayList < > ();
singlePermutation.add(items.get(i));
singlePermutation.add(items.get(j));
singlePermutation.add(items.get(k));
// all permutations
allPermutations.add(singlePermutation);
}
}
}
for (ArrayList < Integer > permutation: allPermutations) {
System.out.println(permutation);
}
System.out.println(allPermutations.size());
}
Moved solution from question to answer:
Solution:
Thanks to older coder, I managed to find the solution.
public class PermutationTest10 {
// a is the original array
// k is the number of elements in each permutation
public static ArrayList<ArrayList<Integer>> choose(ArrayList<Integer> a, int k) {
ArrayList<ArrayList<Integer>> allPermutations = new ArrayList<ArrayList<Integer>>();
enumerate(a, a.size(), k, allPermutations);
return allPermutations;
}
// a is the original array
// n is the array size
// k is the number of elements in each permutation
// allPermutations is all different permutations
private static void enumerate(ArrayList<Integer> a, int n, int k, ArrayList<ArrayList<Integer>> allPermutations) {
if (k == 0) {
ArrayList<Integer> singlePermutation = new ArrayList<Integer>();
for (int i = n; i < a.size(); i++){
singlePermutation.add(a.get(i));
}
allPermutations.add(singlePermutation);
return;
}
for (int i = 0; i < n; i++) {
swap(a, i, n-1);
enumerate(a, n-1, k-1, allPermutations);
swap(a, i, n-1);
}
}
// helper function that swaps a.get(i) and a.get(j)
public static void swap(ArrayList<Integer> a, int i, int j) {
Integer temp = a.get(i);
a.set(i, a.get(j));
a.set(j, temp);
}
// sample client
public static void main(String[] args) {
// n is the end item of the array.
// if n = 5, the array is [0, 1, 2, 3, 4, 5]
// k is the number of elements of each permutation.
int n =5;
int k =3;
// create original array
ArrayList<Integer> elements = new ArrayList<> ();
for (int i =0; i < n; i ++){
elements.add(i);
}
ArrayList<Integer> a = new ArrayList<> ();
for (int i = 0; i < n; i ++){
a.add(elements.get(i));
}
System.out.println(choose(a, k));
}
}

Categories