I'm trying a simple intuition to transpose a matrix in place.
I'm trying to swap elements of matrix[i][j] and matrix[j][i] but it is not working, I'm wondering what is happening behind the scene.
class Solution {
public int[][] transpose(int[][] matrix) {
for(int i = 0; i < matrix.length; i++){
for(int j = 0; j < matrix[0].length; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
return matrix;
}
}
Output
For matrix -> [[1,2,3],[4,5,6],[7,8,9]]
It is giving output -> [[1,2,3],[4,5,6],[7,8,9]]
but the expected output should be -> [[1,4,7],[2,5,8],[3,6,9]]
You are transposing each pair of elements twice, which puts them back how they were.
One solution would be to change for(int j = 0; in the inner loop to for(int j = i + 1;. This would make sure that each pair of elements is only transposed once.
Also be aware that this general solution only works for square matrices.
how about this way?
public int[][] transpose(int[][] matrix) {
int[][] result = new int[matrix.length][matrix[0].length];
for(int i = 0; i < matrix[0].length; i++){
for(int j = 0; j < matrix.length; j++){
result[j][i] = matrix[i][j];
System.out.println(Arrays.deepToString(result));
}
}
return result;
}
Related
I am trying to create a program, which counts the minimum of each dimension in a two dimensional array. So for ex. if i had an array:
int[][] test = {{1,2,3},{2,3,4},{4,5,6}}
the program would display: [1,2,4] - the minimum of each dimension.
For that I've created a method called minimum, which looks like this
static int[] minimum(int[][] arr) {
int[] result = new int [arr.length];
for (int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr[i].length; j++) {
int min = arr[i][0];
if(arr[i][j] < min) {
min = arr [i][j];
result [i] = min;
} else{
}
}
}
return result;
}
But when i call out this method in my main, with a sample array
public static void main(String[] args) {
int[][] arr = {{1,2,3,},{3,4,5},{6,6,6}};
System.out.println(Arrays.toString(minimum(arr)));
}
The program displays [0,0,0,]. Do You have any clue where is the problem and how to fix it?
The problem is that if the first element in the array is min, it never gets recorded to the result array. Try:
static int[] minimum(int[][] arr) {
int[] result = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
result[i] = arr[i][0];
for (int j = 1; j < arr[i].length; j++) {
if (arr[i][j] < result[i]) {
result[i] = arr[i][j];
}
}
}
return result;
}
Note that there needs to be at least one element per row in the input matrix for the above function; add a conditional or use Integer.MIN_VALUE to handle empty rows if you wish.
This should work. You reset the min to the first element every time. So you are basically comparing if there is any value smaller than the first one.
static int[] minimum(int[][] arr){
int[] result = new int [arr.length];
for (int i = 0; i < arr.length; i++){
result[i] = Integer.MAX_VALUE;
for(int j = 0; j < arr[i].length; j++){
if(arr[i][j] < result[i]) {
result [i] = arr[i][j];
}
}
}
return result;
}
I have an ArrayList and I want to create a method that will turn it into a 2d array, int[][].
This new 2d array will represent a matrix and it has to be square, so for example if I use [8, 2, 3, 0] the ressult will be {8,2}
{3,0}
public static int[][] convertIntegers(ArrayList<Integer> integers){
int m = (int) Math.sqrt(integers.size());
int[][] ret = new int[m][m];
int cont = 0;
for(int i=0; i<m+1 ; i++)
{
for(int j=0; j<m; j++)
{
cont = cont + 1;
ret[i][j] = integers.get(cont);
;
}
}
return ret;}
Your implementation is almost ok, except for some off-by-one errors:
You need to increment cont after the integers.get call, not before. If you increment before, then the first element of the list will be skipped. An easy way to fix that is to move the incrementing inside the inner loop, counting it together with j.
The outer loop should go until i < m instead of i < m + 1
With the errors fixed:
for (int i = 0, cont = 0; i < m; i++) {
for (int j = 0; j < m; j++, cont++) {
ret[i][j] = integers.get(cont);
}
}
Btw, another way is without using cont at all,
calculating the correct position using i, j and m:
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
ret[i][j] = integers.get(i * m + j);
}
}
I have a NxN matrix and it trying to transpose it by this code:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < mat_size; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
it doesn't work, what is the problem? thanks in advance.
It doesn't work since you're swapping the whole matrix with itself. What you need to do is exchange the upper triangle with the lower one:
for(int j = 0; j < i; ++j) {
is one way.
Going from 0 to mat_size will get you reorder the whole matrix two times, getting the original one again.
change to :
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
You need to swap only if j > i. So the inner loop must start at i+1. For j==i (the center diagonal) no swapping is needed, too.
Your solution doesn't work because you're actually swapping twice (once with j=x and i=y and once with j=y and i=x.
For example the (2,5) is swapped for i=2,j=5 and i=5,j=2. Swap twice does nothing.
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
This is because the elements that you swap in the lower triangle of the matrix gets swapped again when the iteration reaches the other side of the diagonal. That is the element is swapped twice which results in nothing.
Try:
for(int i = 0; i < mat_size; ++i) {
for(int j = 0; j < i; ++j) {
double tmpJI = get(j, i);
put(j, i, get(i, j));
put(i, j, tmpJI);
}
}
This is the assignment: Write a method that sorts the elements of a matrix with 2 dimensions. For example
sort({{1,4}{2,3}})
would return a matrix
{{1,2}{3,4}}.
I dont know what im doing wrong in my code cause the output i get is 3.0, 3.0, 4.0, 4.0.
This is what i have so far any help would be appreciated.
public static void main(String[] args) {
double[][] array = { {1, 4}, {2, 3} };
double[][] new_array = sort(array);
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array.length; j++) {
System.out.print(new_array[i][j] + " ");
}
}
}
public static double[][] sort(double[][] array) {
double[] storage = new double[array.length];
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array.length; j++) {
storage[i] = array[i][j];
}
}
storage = bubSort(storage);
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array.length; j++) {
array[i][j] = storage[i];
}
}
return array;
}
public static double[] bubSort(double[] list) {
boolean changed = true;
double temp;
do {
changed = false;
for (int j = 0; j < list.length -1; j++)
if (list[j] > list[j + 1]) {
temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
changed = true;
}
} while (changed);
return list;
}
}
The main problem that you are experiencing is how you are copying the values from the 2d array into the 1d array. You are actually only copy two values into an array of length 2. The length of a 2d array is not the full m x n length.
I will give a small hint how you can go about copying from the 2d array into the 1d array, but it is up to you to figure out how to copy back from the 1d array into the 2d array. Also, how would you go about finding the full length of the array?
double[] storage = new double[4];//You should calculate this value
int k = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
storage[k++] = array[i][j];
}
}
Your bubble sort works fine, but then you are copying the values back wrong. Try printing the array storage after the sort and you will see that it is now correct.
You are overwriting your storage array you have it set to array[i]. Because it is in the for loop you are setting storage[0] = array[0][0] then setting storage[0] = array[0][1]. This causes you to only pick up the last number in that dimension of the array. Likewise, when you are reading them back out you are inserting the same number twice. Since 4 and 3 are the last two numbers in their respective dimensions this shows that you are sorting the array. You need a for loop for storage that is set < array.length and store your values inside that.
I would like to loop over half of an array in Java; this is because the matrix will be completely symmetric. If I loop throw i columns and j rows, every time I do an operation of matrix[i][j] I will do the exact same operation to matrix[j][i]. I should be able to save time by not looping over half of the matrix. Any ideas on the easiest way to do this?
If you're trying to get a triangle:
for(int i=0; i<array.length; i++){
for(int j=0; j<=i; j++){
..do stuff...
}
}
for (i = 0;i < size; ++i) {
for (j = 0; j < i; ++j) {
result = do_operation(i,j);
matrix[i][j] = result;
matrix[j][i] = result ;
}
}
So you invoke the operation method do_operation only once for each pair.
for(int i = 0; i<array.length; i++){
for(int j = 0; j < array[i].length - i; j++){
// operation here
}
}
Maybe I'm missing something here, but let's say you have two arrays representing your rows and columns respectively, and assuming that it's symmetric (as you say):
int dimension = rows.Length;
for(int i=0; i<dimension; i++)
{
int j = (dimension-1) - i; //need dimension-1 to avoid an off-by-one error
DoSomething(matrix[i][j]);
DoSomehting(matrix[j][i]);
}
This solution has the runtime complexity benefit of only iterating over one loop as opposed to two.