I have to traverse an n x n matrix in java (so indices are 0,...,n-1), to assign values to the single elements. I must start from the bottom right and arrive to the top left. The particularity is that I do not have to consider the matrix[n-1][n-1] element, that has been initialised before. The adjacent values depend on each other for initialazing and it must be initialized first.
One way could be inserting an if in the for cycle
for (i = n-1; i >= 0; i--)
for (j = n-1; j >= 0; j--)
if (i == n - 1 && j == n - 1)
//initialize particular value
else
//initialize others
but it seems to me a bit inefficient.
Another way could be to initialize the value matrix[n-1][n-1] outside the cycle, then doing 3 for cycles (one for the bottom line, one for the rightest column, one for the other elements). But it seems a bit inelegant.
So I'm searching, if exists, for a solution that involves only two annidate for, and without a control in every cycle (like first example).
Here is an approach that uses one loop through the matrix which makes it easy to avoid matrix[n-1][n-1]. Not sure how the calculations compares to an if though from a performance perspective
int[][] matrix = new int[n][n];
int current = n * n - 2;
int row = 0;
int col = 0;
while (current >= 0) {
col = current % n;
row = current / n;
matrix[row][col] = //init stuff
current--;
}
I think the solution of Joakim is good except the % and / operations... inspired to this, I've found an interesting variant that avoid them. I've called column index j1 to avoid problems with other "normal" cycles.
matrix[n-1][n-1] = //init code;
int j1 = n-2;
for (int i = n-1; i >= 0; i--) {
for (; j1 >= 0; j1--) {
matrix[i][j1] = //init code;
}
j1 = n-1;
}
Related
Using an ArrayList, I need to subdivide a deck into two sections, one top section, and one bottom section. The top section will be the front of the ArrayList arr. If the size of the ArrayList arr happens to be odd, the top section size must be one more than the bottom section. Below you will see a few more specifications, there seems to be a slight logic error, but I'm having trouble figuring out where. As you can see, I have pretty much all of the code written and I feel as though this should be working. I need to shuffle without using collections.
for(int i =0; i<topHalf.size();i++){
topHalf.size() will return 0 because you have no elements in it yet. When you initialize it you are just allocating a size for the underlying array but the arraylist will have a size of 0...
As an aside you could use the sublist method.
// divide by two and round up
int middle = (int)(arr.size() / 2.0f + 0.5f);
ArrayList<Battleable> topHalf = arr.sublist(0, middle);
ArrayList<Battleable> bottomHalf = arr.sublist(middle, arr.size());
The easiest way is to use the 'sublist' method. You can do:
Double middle = Math.ceil(new Double(arr.size())/2);<br>
topHalf = arr.subList(0, middle.intValue());<br>
bottomHalf = arr.subList(middle.intValue(), arr.size());
The only change I would have made is adding a ternary operator to (simplify?) the code a little bit:
ArrayList<Battleable> topHalf = new ArrayList<Battleable>();
int topSize = arr.size() % 2 == 0 ? arr.size()/2 : (arr.size()/2)+1;
for(int i = 0; i < topSize; i++) {
topHalf.add(i, arr.get(i));
}
ArrayList<Battleable> bottomHalf = new ArrayList<Battleable>();
int count = topHalf.size();
int bottomSize = arr.size() - topHalf.size();
for(int i = 0; i < bottomSize; i++) {
bottomHalf.add(i, arr.get(count));
count++;
}
int x = 0, y = 0;
int end = arr.size();
for(int i = 0; i < end; i++) {
if(I % 2 == 0) {
arr.add(i, topHalf.get(x));
x++;
} else {
arr.add(i, bottomHalf.get(y));
y++;
}
}
I came across below problem related to Matrix Manipulation.
problem statement
There is a NxN matrix,divided into N * N cells. Each cell has a predefined value. Which would be given as an input. Iteration has to happen K number of times which is also given in the test input. We have to make sure that we pick the optimum/min value of rows/columns at each iteration. Final output is the cumulative sum of optimum value saved at the end of each iteration.
Steps 1. Sum up the individual row and column and find the min sum of rows and columns, (it could be a row or a column, just need the minimum row or a column)
Step 2. Store the sum found above separately
Step 3.
Increment elements of the min. sum row or column. by 1
Repeat steps 1,2,3 from 1 to Kth value
add the sum at each iteration(specified in step2)
output is the sum obtained on on the Kth iteration.
Sample data
2 4
1 3
2 4
Output data
22
I was able to write a code (in java) and tested the same for some sample test cases. The output worked fine. The code works fine for sample data matrix of lower order, say, 2x2,4x4,even till 44x40 (that has less iteration). However, when the matrix size is increased to 100X100 (complex iteration), I see the expected output output values differ at 10s and hundreds place of the digit from the actual output and its random. Since I am not able to find a correct pattern of output vs input. Now, it is taking a toll on me to really debugging 500th loop to identify the issue. Is there any better way or approach to solve such problem related to huge matrix manipulation. Has anyone come across issues similar to this and solved it.
I am mainly interested in knowing the correct approach to solve given matrix problem. What Data structure to use in java. At present, I am using primitive DS and arrays int[] or long[] to solve this problem. Appreciate any help in this regard.
Which data structure?
What you need here is a data structure which allows you to efficiently query and update the minimum sum line. The most commonly used for this is a heap https://en.wikipedia.org/wiki/Heap_(data_structure).
For your purposes it's probably best to just implement the simplest kind, an array-based binary heap:
See here: https://en.wikipedia.org/wiki/Binary_heap
And here: http://courses.cs.washington.edu/courses/cse373/11wi/homework/5/BinaryHeap.java
..for implementation details.
Procedure:
Initialize your heap to size M + N where M, N are the number of rows and columns.
Before the loop, pre-compute the sum of each row and column, and add them as objects to the heap. Also add two arrays A, B which store the row and columon objects separately.
Now heapify the heap array with respect to the line sum attribute. This ensures the heap follows the criterion of the binary heap structure (parent always > children). Read the sources to find out more about how to implement this (quite easy for a fixed array)
For each iteration, look at the first element in the heap array. This is always the one with the smallest line sum. If this is a row object, then increment the sum attribute by N (no. of columns), and increment each object in B (list of columns) by 1. Do the same if it's a column.
After this, always heapify before the next iteration.
At the end, just return the first element's attribute.
Time complexity:
The original naive solution (looping through all columns and rows every time) is .
Using a heap, the heapify operation at each step is (for a binary heap).
This means the total complexity is , FAR smaller. The max term is to compensate for the fact that at each iteration it may be either rows or columns which are incremented.
As a side note, there are other heap structure types which have even better time complexity than the binary heap, e.g. binomial trees, Fibonacci heaps etc. These however are far more complicated, and have higher constant-factor overheads as a result. Thus for your project I feel they are not necessary, as many of them need phenomenal data set sizes to justify for the constant factor overhead.
Besides, they all support the same external operations as the binary heap, as defined by the Abstract Data Structure of Heap.
(heapify is an internal operation specific to the binary heap structure. Quite a few of the other ones are theoretically superior as they do this operation implicitly and "lazily")
O(KN + N*N) Solution:
You can just work with sum of columns and rows, and not store or manipulate them directly.
First sum all the columns and rows, in a 2*N array, first row being sum of columns, a[0][0] is sum of first column, a[0][1] is sum of second column, and second row is sum of rows, a[1][0] sum of first row, etc...
Then do the following for iterating:
Find min in array a .
Add it to the answer.
Add N to the min of row or column selected.
If the min is row add one to all cols and if it is a column add one to all rows.
If needed any further explanation, don't hesitate to comment.
I am doing like this for solving the above problem...
void matrixManipulation() throws IOException {
int N = Reader.nextInt();
int[][] matrix = new int[N][N];
int K = Reader.nextInt();
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[i][j] = Reader.nextInt();
}
}
// System.out.println("********Inital position**********");
// for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// System.out.print(matrix[i][j]);
// }
// System.out.println();
// }
// System.out.println("********Inital position**********");
CalculateSum calculateSum = new CalculateSum();
int[] row = new int[N];
int[] row_clone = new int[N];
int[] col = new int[N];
int[] col_clone = new int[N];
int test =0;
for (int kk = 0; kk < K; kk++) {
row = calculateSum.calculateRowSum(matrix, N);
row_clone = row.clone();
/* just sort it either Arrarys sort or any other ---starts here*/
// for (int i = 1; i < row.length; i++) {
// row_orignial[i] = row[i];
// }
// Arrays.sort(row);
Node root1 = insert(null, row[0], 0, row.length);
for (int i = 1; i < row.length; i++) {
insert(root1, row[i], 0, row.length);
}
sortArrayInOrderTrvsl(root1, row, 0);
/* just sort it either Arrarys sort or any other ---ends here*/
col = calculateSum.calculateColumnSum(matrix, N);
col_clone = col.clone();
/* just sort it either Arrarys sort or any other ---starts here*/
// for (int i = 1; i < col.length; i++) {
// col_orignial[i] = col[i];
// }
// Arrays.sort(col);
Node root2 = insert(null, col[0], 0, col.length);
for (int i = 1; i < row.length; i++) {
insert(root2, col[i], 0, col.length);
}
sortArrayInOrderTrvsl(root2, col, 0);
/* just sort it either Arrary.sort or any other---ends here */
int pick = 0;
boolean rowflag = false;
int rowNumber = 0;
int colNumber = 0;
if (row[0] < col[0]) {
pick = row[0];// value
rowflag = true;
for (int i = 0; i < N; i++) {
if (pick == row_clone[i])
rowNumber = i;
}
} else if (row[0] > col[0]) {
pick = col[0];// value
rowflag = false;
for (int i = 0; i < N; i++) {
if (pick == col_clone[i])
colNumber = i;
}
} else if(row[0] == col[0]){
pick = col[0];
rowflag = false;
for (int i = 0; i < N; i++) {
if (pick == col_clone[i])
colNumber = i;
}
}
test= test + pick;
if (rowflag) {
matrix = rowUpdate(matrix, N, rowNumber);
} else {
matrix = columnUpdate(matrix, N, colNumber);
}
System.out.println(test);
// System.out.println("********Update Count"+kk+" position**********");
// for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// System.out.print(matrix[i][j]);
// }System.out.println();
// }
// System.out.println("********Update Count"+kk+" position**********");
}
// System.out.println("********Final position**********");
// for (int i = 0; i < N; i++) {
// for (int j = 0; j < N; j++) {
// System.out.print(matrix[i][j]);
// }System.out.println();
// }
// System.out.println("********Final position**********");
// System.out.println(test);
}
I started to read the famous "cracking the Coding Interview" book and I want to do the following exercice.
Write an algorithm such that if an element in an MxN matrix is 0, its entire row and column is set to 0.
Here is the author's solution :
public static void setZeros(int[][] matrix) {
int[] row = new int[matrix.length];
int[] column = new int[matrix[0].length];
// Store the row and column index with value 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length;j++) {
if (matrix[i][j] == 0) {
row[i] = 1;
column[j] = 1;
}
}
}
// Set arr[i][j] to 0 if either row i or column j has a 0
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
if ((row[i] == 1 || column[j] == 1)) {
matrix[i][j] = 0;
}
}
}
}
I agree with the author about the main idea. We don't have to store the position of '0' in the matrix but only the position of the rows and columns that are concernerd. But what I found a little "strange" in her solution is that at the end, she did a loop on all the cells of the matrix, which is not necessary in my opinion.
Here is my solution :
static int[][] replaceMatrix(int[][] matrix){
int M = matrix.length;
int N = matrix[0].length;
boolean[] row = new boolean[M] ;
boolean[] column = new boolean[N];
for (int i =0; i< M; i++) {
for (int j = 0; j<N; j++ ){
if (matrix[i][j] == 0) {
row[i] = true;
column[j] = true;
}
}
}
for (int i =0; i<M; i++){
if (row[i]){
for (int k =0; k<N; k++){
matrix[i][k]=0;
}
}
}
for (int j =0; j<N; j++){
if (column[j]){
for (int k =0; k<M; k++){
matrix[k][j]=0;
}
}
}
I'am newbie in programmation so I'm not totaly sure about this. But in my solution, if we except the first step which is to store the 0 positions, my second part of my programme have a time complexity of O(M+N) while her solution has a complexity of O(M*N).
The problem is that the general complexity will be the same O(M*N + (M+N)) is the same that having the complexity O(2*M*N), no? (I'm not totally sure).
For example, if it's a matrix with M=N, so the two complexity of the two programs will be O(M^2).
I really want to know if there is a difference or not about complexity in this case?
ps : I read that the space complexity can be improved with a bit vector. But I really didn't understand. Can you just give me a general idea about it (in Java)?
Time complexity of your last two for loops is still O(M*N) as in worst case inner for loop will be running maximum value of k times.
There is technically no difference in your and the author's solution because both of you have traversed the entire matrix.So both codes are same ** if we have to consider big O notation**
In fact the author's code is a little bit( by little bit I do not mean a different time complexity) better. Here is the reason:
Suppose in your boolean array of rows, all rows are set true. Then in your case you will go through all rows and through each element of every row which is basically traversing the entire matrix.
Suppose in your boolean array of columns, all columns are set true. Then in your case you will go through all columns and through each element of every column which is basically traversing the entire matrix.
So you will in effect traverse the entire matrix twice. But the time complexity of the codes is the same because O(M*N) and O(2*M*N) is same.
You have already done saving space, since you used boolean data type.
I have to find all possibilities to distribute n things to k containers. The containers all should have a different size so I made k inner for-loops for counting every possibility. Sorry for the bad explanation, but my english is not that good.
Example code that works for 3 Containers:
for (int i = 0; i < container[0]; i++)
for (int j = 0; j < container[1]; j++)
for (int k = 0; k < container[2]; k++)
if ((i + j + k) == n)
Possibilities++;
Now i need to know how to make k for loops so that it works for 2 and for 10.
Thanks
I am assuming that containers holds the size of each container. Perhaps the simplest solution would be to just set the size of any containers you don't use to zero. Then you can have (say) 10 nested loops but if there are only 2 containers then set all the sizes above 2 to zero.
However nested loops are not really the best way to handle this. This is likely to be a good use for recursion.
private int combinationCount(int[] containerSizes, int from, int total) {
if (total == 0 || from == containerSizes.length - 1)
return 1;
int combinations = 0;
for (int i = 0; i <= Math.min(total, containerSizes[from]); i++)
combination += combinationCount(containerSizes, from + 1, total - i);
return combinations;
}
This would be called with combinationCount(containers, 0, n). You could remove the from argument altogether by either copying the array in each recursive call or passing a List and then a sublist in the recursive calls.
Here is my test code for your information:
System.out.println(combinationCount(IntStream.range(10, 30).toArray(), 0, 10));
Which returns 20030010
I'll explain how this works:
if (total == 0 || from == containerSizes.length - 1)
return 1;
If the total of the remaining containers is zero then there's only 1 combination because all the remaining containers must be empty. Similarly if there's only one container left there's only 1 combination because it must have all the remaining items.
int combinations = 0;
for (int i = 0; i <= Math.min(total, containerSizes[from]); i++)
combination += combinationCount(containerSizes, from + 1, total - i);
return combinations;
The current container might contain anything from zero to all the items. So iterate through those and total up all the combinations for the remaining containers that add up to the target minus the items in the current container.
I'm working on this bacteria life game thing I have to make.
Basically I have a 2d string array let's say 20 by 20.
What would be the best way to check all 8 spots around a certain index. Each index is suppose to represent a bacteria. For each bacteria(index) I have to check to see if any of the 8 spots around this index has another bacteria in it, if the index has a bacteria in it, it's represented simply by a "*", asterik.
What would be the best way to go about checking all 8 spots around each index, because based on what is in the indices around a certain index I have to make certain changes etc.
The only idea I have come up with is having a bunch of if statements to check all 8 spots, I was wondering if there is a better way to do this
ex:
row 1 - www , row 2 = wOw , row 3 - www ,
if I am at the O index, what would be the best way to check all the index spots around it for a certain string.
Sorry, I am not very good at explaining my problems, bad english :o.
thanks for any of the help.
so you have something like this
char[][] table = new char[20][20]
for(int i = 0; i < 20; i++) {
for(int j = 0; j < 20; j++) {
int surroundingBacteria = 0;
for(int x = max(i-1,0); x < min(20,i+1); x++) {
for(int y = max(i-1,0); y < min(20,i+1); y++) {
if(table[x][y] == '*') surroundingBacteria++;
}
}
switch(surroundingBacteria) {
// put your case logic here
}
}
}
Here is how I've accomplished this in the past:
for(int x = -1; x<=1; x++){
if ( i+x < xLength && i+x >= 0){
for(int y = -1; y<=1; y++){
if(j+y < yLength && j+y >= 0){
//logic goes here
}
}
}
}