Sorting a 2D array/Matrix by its diagonals - java

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];
}
}
}
}

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

How do I split an array list into two array lists based on a delimiter?

Suppose that I have an Array list of Array lists:
A = [2, 5, 6], [1, 6, 1], [], [7, 7], [4, 2], [9, 3]]
and I want to split them at the index where the element of the array list has the size of 0 so that it will look like this
x = [[2, 5, 6], [1, 6, 1]]
y = [[7, 7], [4, 2], [9, 3]]
but whenever I run my loop it comes out like this:
for(int i = 0; i < A.size(); i++) {
ArrayList temp= A.get(i);
int size = temp.size();
if(size != 0) {
x.add(temp);
}
y.add(temp);
}
x = [[2, 5, 6], [1, 6, 1], [7, 7], [4, 2], [9, 3]]
y = [[2, 5, 6], [1, 6, 1], [], [7, 7], [4, 2], [9, 3]]
Can anyone please help me figure this out?
You need to keep track of the destination array like this:
boolean addToX = true;
for(ArrayList temp : A) {
if(temp.isEmpty()) {
addToX = false;
} else if(addToX) {
x.add(temp);
} else {
y.add(temp);
}
}
You logic is off. Currently you are avoiding writing the empty list into x; other than that you always write to both x and y.
You can have a boolean to say which list the data must be written to. Once you see a list with size 0, switch the flag.
boolean writeToX = true;
for(int i = 0; i < A.size(); i++) {
ArrayList temp= A.get(i);
int size = temp.size();
if(size == 0) {
writeToX = false;
continue;
}
if (writeToX) {
x.add(temp);
} else {
y.add(temp);
}
}
Sidenote: Avoid using raw types.
What is a raw type and why shouldn't we use it?
Try this, add a boolen flag to identify :-
boolean flag=false;
for(int i = 0; i < A.size(); i++) {
ArrayList temp= A.get(i);
int size = temp.size();
if(size != 0 && flag==false) {
x.add(temp);
}else if(size==0) {
flag=true;
}else if(size != 0 && flag==true){
y.add(temp);
}
it is normal because you are just not putting the empty element to x but you are putting all other elements to x and y. You can have a boolean parameter, such as isNullArrayCome and check it on every iteration. Here it is
boolean isNullArrayCome = false;
for(int i = 0; i < A.size(); i++) {
ArrayList temp= A.get(i);
int size = temp.size();
if(size == 0 ) {
isNullArrayCome = true;
}
if(!isNullArrayCome){
x.add(temp);
} else {
y.add(temp);
}
}

Java ArrayOutOfBoundException in ArrayList

The question is Define a cluster in an integer array to be a maximum sequence of elements that are all the same value. For example, in the array {3, 3, 3, 4, 4, 3, 2, 2, 2, 2, 4} there are 5 clusters, {3, 3, 3}, {4, 4}, {3}, {2, 2, 2, 2} and {4}. A cluster-compression of an array replaces each cluster with the number that is repeated in the cluster. So, the cluster compression of the previous array would be {3, 4, 3, 2, 4}. The first cluster {3, 3, 3} is replaced by a single 3, and so on.
public static void main(String[] args) {
int[] givenArray = {1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
System.out.println("Clustered Array = " + Arrays.toString(isTrivalent(givenArray)));
}
public static int[] isTrivalent (int[] a){
List<Integer> cluster = new ArrayList<Integer>();
for (int i=0; i<a.length ; i++ ) {
if(i == 0){
cluster.add(a[i]);
}else{
if(cluster.get(i-1) != a[i]) cluster.add(a[i]);
}
}
int[] arr = new int[cluster.size()];
for (int j =0; j<cluster.size() ; j++) {
arr[j] = cluster.get(j);
}
return arr;
}
But I am getting an ArrayOutOfBoundException. What am I doing wrong?
Change
if(cluster.get(i-1) != a[i]) cluster.add(a[i]);
to
if(a[i-1] != a[i]) cluster.add(a[i]);
cluster.get(i-1) may not exist.
This is happening because when you check
if(cluster.get(i-1) != a[i])
it is not necessary that the cluster arraylist will actually have size of atleast i-1 since you are skipping a lot of array elements. You need to change your condition to
if(cluster.get(cluster.size()-1) != a[i])
or equivalently (as suggested in previous answer)
if(a[i-1] != a[i])
for this code to work as intended.
public static void main(String[] args) {
int[] givenArray = {1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
System.out.println("Clustered Array = " + Arrays.toString(isTrivalent(givenArray)));
}
public static int[] isTrivalent(int[] a) {
List<Integer> cluster = new ArrayList<Integer>();
for (int i = 0; i < a.length; i++) {
if (i == 0) {
cluster.add(a[i]);
} else {
if (cluster.get(cluster.size() - 1) != a[i]) {
cluster.add(a[i]);
}
}
}
int[] arr = new int[cluster.size()];
for (int j = 0; j < cluster.size(); j++) {
arr[j] = cluster.get(j);
}
return arr;
}

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

Finding all possible combinations of a given array in Java

I'm working on a problem in Java to find all possible combinations given an arbitrary starting array, by decrementing the values one at a time of each item in the array until the value 1 is reached at each index.
I've started on the below test case but haven't got very far.
I would like some help in solving my problem please.
import org.junit.Assert;
import org.junit.Test;
public class ComboTest
{
#Test
public void test()
{
int[][] answers = {
{4, 3, 2}, {3, 3, 2}, {2, 3, 2}, {1, 3, 2},
{4, 2, 2}, {3, 2, 2}, {2, 2, 2}, {1, 2, 2},
{4, 1, 2}, {3, 1, 2}, {2, 1, 2}, {1, 1, 2},
{4, 3, 1}, {3, 3, 1}, {2, 3, 1}, {1, 3, 1},
{4, 2, 1}, {3, 2, 1}, {2, 2, 1}, {1, 2, 1},
{4, 1, 1}, {3, 1, 1}, {2, 1, 1}, {1, 1, 1},
};
int[] start = {4, 3, 2};
int dim = 1;
for (int i = 0; i < start.length; i++)
{
dim *= start[i];
}
int[][] combos = new int[dim][start.length];
for (int i = 0; i < combos[0].length; i++)
{
combos[0][i] = start[i];
}
for (int i = 1; i < combos.length; i++)
{
for (int j = 0; j < combos[i].length; j++)
{
int k = combos[i - 1][j] - 1;
if (k < 1)
{
k = start[j];
}
combos[i][j] = k;
}
}
for (int i = 0; i < combos.length; i++)
{
for (int j = 0; j < combos[i].length; j++)
{
Assert.assertEquals(answers[i][j], combos[i][j]);
}
}
}
}
This is a simple state search problem. You have a starting state, and you can expand it (create its children) following some criteria. In your case, by decrementing one of the values, but not below some lower bound.
If you're not familiar with DFS or BFS, I suggest reading on those. In the meantime, here's the code (perhaps the solution is not in the format you're expecting, but you can work on it :D):
public class ComboTest {
public static class Combo {
private Integer[] values;
public Combo(Integer[] values) {
this.values = values;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(values);
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Combo)) {
return false;
}
Combo other = (Combo) obj;
if (!Arrays.equals(values, other.values)) {
return false;
}
return true;
}
#Override
public String toString() {
return Arrays.toString(values);
}
}
public static Set<Combo> combos(Combo start, int lowerBound) {
Set<Combo> answers = new HashSet<Combo>();
compute(start, lowerBound, answers);
return answers;
}
private static void compute(Combo start, int lowerBound, Set<Combo> answers) {
Deque<Combo> dfsStack = new ArrayDeque<Combo>();
dfsStack.push(start);
while (!dfsStack.isEmpty()) {
Combo current = dfsStack.pop();
answers.add(current);
for (Combo next : expand(current, lowerBound)) {
if (!answers.contains(next)) {
dfsStack.push(next);
}
}
}
}
private static List<Combo> expand(Combo current, int lowerBound) {
List<Combo> nexts = new ArrayList<Combo>();
for (int i = 0; i < current.values.length; i++) {
if (current.values[i] > lowerBound) {
Integer[] copyCurrent = Arrays.copyOf(current.values, current.values.length);
copyCurrent[i]--;
nexts.add(new Combo(copyCurrent));
}
}
return nexts;
}
public static void main(String[] args) {
Combo start = new Combo(new Integer[] { 4, 3, 2 });
Set<Combo> combos = combos(start, 1);
for (Combo combo : combos) {
System.out.println(combo);
}
System.out.println(combos.size());
}
}
Output:
[4, 3, 1]
[2, 1, 1]
[3, 2, 1]
[1, 1, 2]
[2, 2, 2]
[3, 3, 2]
[4, 3, 2]
[4, 2, 1]
[3, 1, 1]
[2, 1, 2]
[3, 2, 2]
[4, 1, 1]
[4, 2, 2]
[3, 1, 2]
[4, 1, 2]
[1, 3, 1]
[1, 2, 1]
[2, 3, 1]
[1, 3, 2]
[1, 1, 1]
[2, 2, 1]
[3, 3, 1]
[1, 2, 2]
[2, 3, 2]
24
you Seaching all permutation of an Array with n elements so this is Already asked here
Permutation algorithm for array of integers in Java
This is not my Answer im Only Refering to it
static ArrayList<int[]> permutations(int[] a) {
ArrayList<int[]> ret = new ArrayList<int[]>();
permutation(a, 0, ret);
return ret;
}
public static void permutation(int[] arr, int pos, ArrayList<int[]> list){
if(arr.length - pos == 1)
list.add(arr.clone());
else
for(int i = pos; i < arr.length; i++){
swap(arr, pos, i);
permutation(arr, pos+1, list);
swap(arr, pos, i);
}
}
public static void swap(int[] arr, int pos1, int pos2){
int h = arr[pos1];
arr[pos1] = arr[pos2];
arr[pos2] = h;
}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class New{
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
System.out.println("ENTER THE ARRAY SIZE");
int n=in.nextInt();
System.out.println("ENTER THE ARRAY VALUES");
int[] a=new int[n];
String s="";
for(int i=0;i<n;i++)
{
a[i]=in.nextInt();
s=s+(char)a[i];
}
List<String> hs=mac(s);
System.out.println("THE COMBINATIONS ARE");
for(String str:hs)
{
char[] ch=str.toCharArray();
for(int i=0;i<ch.length;i++)
{
System.out.print((int)ch[i]);
}
System.out.println();
}
}
public static List<String> mac(String s)
{
List<String> ss=new ArrayList<String>();
if(s==null)
{
return null;
}
else if(s.length()==0)
{
ss.add("");
}
else
{
String str=s.substring(1);
char c=s.charAt(0);
List<String> hs=mac(str);
for(String st:hs)
{
for(int i=0;i<=st.length();i++)
{
ss.add(sru(st,c,i));
}
}
}
return ss;
}
public static String sru(String s,char c,int i)
{
String start=s.substring(0,i);
String end=s.substring(i);
return start+c+end;
}
}
Easier method:
There's a library called Google Guava, that will do this thing for you.
You can find it here: https://github.com/google/guava
Idk if this code fits for you but anyway here's the code. Hope it helps :) ...
Collection<List<String>> permutations = null;
String[] foo = //your array in here
permutations = Collections2.permutations(Lists.newArrayList(foo));
//use for each loop to read
for (List<String> permutation : permutations) {
//Output here
}

Categories