I would like to know how could I take in a negative value for d in the following code. This means, how could I traverse the array backwards and rotate its elements.
catchArray(int [] arr, int d)
{
int [] bArr = new int[arr.length];
for(int i = 0; i < bArr.length; i++)
{
bArr[(i + d) % bArr.length] = arr[i];
}
return bArr;
}
This is my answer for LeetCode Rotate Array assignment. Thank you in advance.
Just normalize "d" at the start of the program. If it's negative, then correct it.
Let's say the array length is 10 and d is -1. You'd get the same rotation if length was 10 and d was 9. That's all the adjustment at the start of the function is doing.
catchArray(int [] arr, int d)
{
d = d % arr.length;
if (d < 0)
{
d += arr.length;
}
int [] bArr = new int[arr.length];
for(int i = 0; i < bArr.length; i++)
{
bArr[(i + d) % bArr.length] = arr[i];
}
return bArr;
}
If the array is e.g. size 10, then a -1 rotation is the same as a +9 rotation.
In Java, the % remainder operator will return a negative value, if the quotient is negative, e.g. -12 % 10 and -2 % 10 will both return -2.
So, to get a normalized rotation value, we do this:
MIN_VALUE <= d <= MAX_VALUE
d % size -> -size < d < size
+ size -> 0 < d < size * 2
% size -> 0 <= d < size (normalized range)
Combined:
d = (d % arr.length + arr.length) % arr.length
That normalizes d to rotate less than one full round to the right.
static int[] catchArray(int[] arr, int d) {
d = (d % arr.length + arr.length) % arr.length;
int[] bArr = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
bArr[(i + d) % arr.length] = arr[i];
}
return bArr;
}
Tests
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, -8)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, -2)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, -1)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 0)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 1)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 2)));
System.out.println(Arrays.toString(catchArray(new int[] {1,2,3,4,5}, 8)));
Output
[4, 5, 1, 2, 3]
[3, 4, 5, 1, 2]
[2, 3, 4, 5, 1]
[1, 2, 3, 4, 5]
[5, 1, 2, 3, 4]
[4, 5, 1, 2, 3]
[3, 4, 5, 1, 2]
Related
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)
I wrote a method for finding and deriving the largest number of increasing (decreasing) elements of the matrix, going in a row. But it seems that the code is not quite good.
private void findLargestIncreasingAndDecreasingElements() {
int[][] matrix = getMatrix();
int[] oneArray = new int[matrix.length * matrix.length];
int r = 0;
int min = 0;
int max = 0;
int h = 0;
int m = 0;
int h1 = 0;
for (int[] x : matrix) {
int c = 0;
for (int z : x) {
oneArray[c++] = z;
}
}
for (int i = 0; i < oneArray.length - 1; i++) {
if (oneArray[i] < oneArray[i + 1]) {
r += 1;
if (r > max) {
max = r;
h = i + 1;
}
} else {
r = 0;
}
if (oneArray[i] > oneArray[i + 1]) {
m += 1;
if (m > min) {
min = m;
h1 = i + 1;
}
} else {
m = 0;
}
}
System.out.println("Maximum sequence of increasing numbers:");
int[] l = new int[max + 1];
System.arraycopy(oneArray, (h - max), l, 0, (max + 1));
System.out.println(java.util.Arrays.toString(l) + " " + (max + 1));
System.out.println("Maximum sequence of decreasing numbers:");
int[] t = new int[min + 1];
System.arraycopy(oneArray, (h1 - min), t, 0, (min + 1));
System.out.println(java.util.Arrays.toString(t) + " " + (min + 1));
}
Maybe someone knows how to make the algorithm better?
Sometimes incorrect output. For example:
{{-3, -3, 3, -5, 2}, {1, -2, 5, -2, -1}, {5, -3, -4, 2, 5}, {4, 4, -2, 3, 5}, {-2, 5, 4, 0, 0}}
outputs incremental:[-2, 5]
although there is [-2, 3, 5]
In the code that flattens the matrix, c gets reset on each pass through the outer loop, so only the final row of the matrix actually makes it into oneArray. Moving the int c = 0; line out of the loop will allow the whole matrix to get copied into oneArray so your code can find sequences outside the final row.
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));
}
}
I keep getting an out of bounds error whenever i try to run my code. Does anyone know what is wrong with it? I can't seem to figure it out.
public class Swapper{
/**
This method swaps the first and second half of the given array.
#param values an array
*/
public void swapFirstAndSecondHalf(int[] values) {
// your work here
int[] first = new int[values.length/2];
int[] second = new int[values.length/2];
for(int i = 0; i < values.length / 2; i++) {
second[i] = values[i];
}
for (int j = values.length / 2; j < values.length; j++) {
first[j] = values[j];
}
for(int k = 0; k < values.length / 2; k++) {
values[k] = first[k];
}
for(int l = values.length / 2; l < values.length; l++) {
values[l] = second[l];
}
}
// This method is used to check your work
public int[] check(int[] values) {
swapFirstAndSecondHalf(values);
return values;
}
}
int[] first = new int[values.length/2];
So indexes [0..values.length/2 - 1] are valid for first.
for (int j=values.length/2; j<values.length; j++)
{
first[j] = values[j];
}
So with the first value of j being values.length/2, it's already out of bounds.
You need to practice debugging, placing a break point and tracing the code as it executes.
You could have used System.arraycopy() instead of all the for looping.
public static void main(String[] args) throws Exception {
int[] values = {1, 2, 3, 4, 5};
values = swapFirstAndSecondHalf(values);
System.out.println(Arrays.toString(values));
values = new int[]{1, 2, 3, 4, 5, 6};
values = swapFirstAndSecondHalf(values);
System.out.println(Arrays.toString(values));
}
public static int[] swapFirstAndSecondHalf(int[] values) {
boolean evenSize = values.length % 2 == 0;
int half = values.length / 2;
int[] swapper = new int[values.length];
System.arraycopy(values, evenSize ? half : half + 1, swapper, 0, half);
System.arraycopy(values, 0, swapper, evenSize ? half : half + 1, half);
// The middle number stays the middle number
if (!evenSize) {
swapper[half] = values[half];
}
return swapper;
}
Results:
[4, 5, 3, 1, 2]
[4, 5, 6, 1, 2, 3]
If you're wanting the middle number, for an odd sized array, to be part of the second half then the swapFirstAndSecondHalf() would look like this:
public static int[] swapFirstAndSecondHalf(int[] values) {
boolean evenSize = values.length % 2 == 0;
int half = values.length / 2;
int[] swapper = new int[values.length];
System.arraycopy(values, half, swapper, 0, evenSize ? half : half + 1);
System.arraycopy(values, 0, swapper, evenSize ? half : half + 1, half);
return swapper;
}
Results:
[4, 5, 3, 1, 2]
[4, 5, 6, 1, 2, 3]
Allocating new arrays is a waste of space. Just swap the halves in-place:
public static void swapFirstAndSecondHalf(int[] values) {
final int len = values.length / 2;
final int offset = values.length - len;
for (int i = 0; i < len; i++) {
int temp = values[i];
values[i] = values[offset + i];
values[offset + i] = temp;
}
}
The code allows odd length, and will leave center value alone.
Suppose, I have an array like
[1,2,3,4,5,6,7,8,9,10,11,12]
Are there any standard methods to transform it to the table with N columns?
For example, if N=3:
[[1,2,3],[4,5,6],[7,8,9],[10,11,12]]
or if N=4:
[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
etc.
With Java 8, you can use an IntStream to generate the corresponding indexes that you'll give to Arrays.copyOfRange.
I answered a sort of a similar question and you can find the logic there but here's it's slightly modified to take the array as parameter:
static List<int[]> partitionIntoList(int[] arr, int pageSize) {
return IntStream.range(0, (arr.length + pageSize - 1) / pageSize)
.mapToObj(i -> Arrays.copyOfRange(arr, i * pageSize, min(pageSize * (i + 1), arr.length)))
.collect(toList());
}
static int[][] partitionIntoArray(int[] arr, int pageSize) {
return IntStream.range(0, (arr.length + pageSize - 1) / pageSize)
.mapToObj(i -> Arrays.copyOfRange(arr, i * pageSize, min(pageSize * (i + 1), arr.length)))
.toArray(int[][]::new);
}
Note that if pageSize does not partition perfectly the input's size, the remaining elements are added in the last int array.
For example,
partitionIntoArray(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, 4);
outputs:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
and if you take a page size of 5, the two last elements will be added to a third array:
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12]]
Hope it helps! :)
Just using for loops:
int[] array = {1,2,3,4,5,6,7,8,9,10,11,12};
int n = 3;
int m = (int) Math.ceil( ( (double) array.length ) / n );
int[][] table = new int[m][n];
int k = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (k < array.length) {
table[i][j] = array[k];
k++;
}
}
}
The output should be what you are asking for.
Not really but you can create one easily using some math and a loop:
public int[][] getTable(int[] arr, int n) {
int[][] table = new int[(int)Math.ceil(arr.length / (float)n)][n];
for (int i = 0, row = 0, column = 0; i < arr.length; i++) {
if (i % n == 0 && i != 0) {
row++;
column = 0;
}
table[row][column++] = arr[i];
}
return table;
}
We could do it this way :
int n = 5; // what ever size you want to break it with
int[] bytes = {1,2,3,4,5,6,7,8,9,10,11,12};
int length = bytes.length;
int counter = 0;
int newSize = length % n == 0 ? length/n : (length/n)+1;
int[][] newArray = new int[newSize][n];
for (int i = 0; i < length - n + 1; i += n)
newArray[counter++] = Arrays.copyOfRange(bytes, i, i + n);
if (length % n != 0)
newArray[counter] = Arrays.copyOfRange(bytes, length - length % n, length);