Rotate Image - Java - algorithm

I am doing a question where, given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise).You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation. This my my code:
class Solution {
public void rotate(int[][] matrix) {
int size = matrix.length;
for(int i = 0 ; i < matrix.length; i++){
for(int y = 0 ; y < matrix[0].length ; y++){
matrix[i][y] = matrix[size - y - 1][i];
System.out.println(size - y - 1);
System.out.println(i);
System.out.println("");
}
}
}
}
This is the input and output results:
input matrix: [[1,2,3],[4,5,6],[7,8,9]]
output matrix: [[7,4,7],[8,5,4],[9,4,7]]
expected matrix: [[7,4,1],[8,5,2],[9,6,3]]
I do not really understand why I am getting duplicates in my output such as the number seven 3 times. On my System.out.println statement, I am getting the correct list of indexes :
2
0
1
0
0
0
2
1
1
1
0
1
2
2
What can be wrong?

I have found a solution. I will try my best to explain it.
Let us consider an array of size 4.
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Now lets look at the numbers present only on the outside of the array:
1 2 3 4
5 8
9 12
13 14 15 16
We will proceed by storing the first element 1 in a temporary variable. Next we will replace 1 by 13, 13 by 16, 16 by 4 and at last 4 by 1 (whose value we already stored in the temporary variable).
We will do the same for all the elements of the first row.
Here is a pseudocode if you just want to rotate this outer ring, lets call it an outer ring:
for i = 0 to n-1
{
temp = A[0][i];
A[0][i] = A[n-1-i][0];
A[n-1-i][0] = A[n-1-0][n-1-i];
A[n-1-0][n-1-i] = A[i][n-1-0];
A[i][n-1-0] = temp;
}
The code runs for a total of n times. Once for each element of first row. Implement this code an run it. You will see only the outer ring is rotated. Now lets look at the inner ring:
6 7
10 11
Now the loop in pseudocode only needs to run for 2 times and also our range of indexes has decreased. For outer ring, the loop started from i = 0 and ended at i = n-1. However, for the inner ring the for loop need to run from i = 1 to i = n-2.
If you had an array of size n, to rotate the xth ring of the array, the loop needs to run from i = x to i = n-1-x.
Here is the code to rotate the entire array:
x = 0;
int temp;
while (x < n/2)
{
for (int i = x;i < n-1-x;i++)
{
temp = arr[x][i];
arr[x][i] = arr[n-1-i][x];
arr[n-1-i][x] = arr[n-1-x][n-1-i];
arr[n-1-x][n-1-i] = arr[i][n-1-x];
arr[i][n-1-x] = temp;
}
x++;
}
Here each value of x denotes the xth ring.
0 <= x <= n-1
The reason why the outer loop runs only for x < n/2 times is because each array has n/2 rings when n is even and n/2 + 1 rings if n is odd.
I hope I have helped you. Do comment if face any problems with the solution or its explanation.

Related

Could someone explain the logic behind the for loops in bubble sort?

So I understand the gist of bubble sort, switching pairs if they're not in the correct order, but what I don't get is the logic behind the limits in the for loops (i.e. i<array.length; and j<array.length-1. Could someone please explain why they are written that way???
int temp = 0;
for (int i = 0; i < data.length; i++) {
for (int j = 1; j < (data.length - i); j++) {
if (data[j - 1] > data[j]) {
temp = data[j - 1];
data[j - 1] = data[j];
data[j] = temp;
}
}
}
It is not at all obvious at first sight but you should note that:
Each time the outer loop completes another element will have "bubbled" its way to the top of the array.
The top part of the array contains the highest elements - this top part grows. Starting with:
3 1 4 1 5 9 2 6 5 4
After one outer loop 9 has bubbled to the top
1 3 1 4 5 2 6 5 4 9
After the second run 6 has bubbled to the top
1 1 3 4 2 5 5 4 6 9
Each time the outer loop runs the inner loop can finish a little bit earlier as we know that the top part of the array will be sorted.

how to get the moore neighbourhood using index of a vector

I have a matrix in Rcpp (C++ for R) which is stored in column order in memory. Ie, it looks like:
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
Now, I have a single for loop that runs from i = 1 to 25 (bear in mind, it is all zero based, but here I am just saying one for convenience).
For every element of the matrix, I want its Moore neighbourhood. This is easy for the elements that are not on the edge. So if our selected index is idx and the size of the square matrix is nrow then we have
leftmid = idx - nrow
lefttop = (idx - nrow) - 1
leftbot = (idx - nrow) + 1
rightmid = idx + nrow
righttop = (idx + nrow) - 1
rightbot = (idx + nrow) + 1
midtop = idx - 1
midbot = idx + 1
But i cant figure out how to deal with the edge cases. For example, if idx = 3, then i want the neighbours:
leftmid = 23
lefttop = 22
leftbot = 24
rightmid = 8
righttop = 7
rightbot = 9
midtop = 2
midbot = 4
It's a little bit more complicated at the corner cases as well. My goal here is to reduce time. I am currently running my program with a double for loop which works, but is slower than reasonable. I want to change it into a single for loop to improve performance.
Edit: I realized the left and right boundaries can be obtained by modulus. So 3 - 5 %% 25 = 23. But I still have the top and bottom edge cases.
It appears you're interested in "cyclic" boundary conditions, where the matrix has a toroidal topology, i.e. the top wraps around to the bottom and the right wraps around to the left.
It might be easier to iterate with four loops, one each over the row and column, and then one each over the row and column of the neighborhood. Something like this should work:
int mooreNeighbors[3][3];
int nRows = 5;
int nCols = 5;
// Loop over the rows and columns of the matrix
for (int i = 0; i < nRows; ++i) {
for (int j = 0; j < nCols; ++j) {
// Loop over the cyclic Moore neighborhood
for (int mnI = 0; mnI < 3; ++mnI) {
for (int mnJ = 0; mnJ < 3; ++mnJ) {
// Sub-matrix indices
int subI = (i - mnI - 1) % nRows;
int subJ = (j - mnJ - 1) % nCols;
// Index into column-dominant matrix
int idx = subI + subJ*nRows;
mooreNeighbors[mnI][mnJ] = matrix[idx];
}
}
}
}
I haven't tried compiling this, but it should be close to correct and clear enough to correct any mistakes. Think of it as pseudo-code.
Also, I'm preferring clarity over optimality. For example, you don't have to do everything in the inner-most loop.

Grid sweeps (traversal) represented with flat vector

I have a grid represented with a flat vector, that is:
-------------
| 6 | 7 | 8 |
-------------
| 3 | 4 | 5 |
-------------
| 0 | 1 | 2 |
-------------
I access the elements with the indices from 0 to grid.size()-1. I want to implement the Fast Sweeping Method. The main purpose of that method is that it does sweeps, that is, grid traversals in specific directions. For the 2D case:
Sweep 1: Right-top
for [row = 0 : nrows-1]
for [col = 0 : ncols-1] --> Result: 0 1 2 3 4 5 6 7 8
Sweep 2: Left-top
for [row = 0 : nrows-1]
for [col = ncols-1 : 0] --> Result: 2 1 0 5 4 3 8 7 6
Sweep 3: Right-bottom
for [row = nrows-1 : 0]
for [col = 0 : ncols-1] --> Result: 6 7 8 3 4 5 0 1 2
Sweep 4: Left-bottom
for [row = nrows-1 : 0]
for [col = ncols-1 : 0] --> Result: 8 7 6 5 4 3 2 1 0
And then computing idx = row*ncols + col.
This implementation is straightforward and its generalization to n dimensions as well, when just nesting for loops. However, I am working on a n-dimensional implementation and I am trying to generalize it in just 2 loops:
while (keepSweeping)
++sweep;
for (idx = init, idx == end, idx += inc)
// Traverse the grid
Computing init, end and inc is being really challenging. Also inc depends on ncols and changes dynamically. For instance, for sweep 2 inc = -1, but every ncols times inc = -1 + 2*ncols, so I achieve to go from 0 to 5.
Any help on how to do it? I am focusing firstly on the 2D case.
EDIT: I saw these threads http://www.cplusplus.com/forum/beginner/68434/ variable nested for loops that suggest to implement the loops recursively. Since I am looking for maximum performance, do you think that is a good idea?
Thank you!
Ok here is my try to answer your problem in the 2D case, using only one loop. Hopefully this is not too far from what you are looking for:
// ****** INITIALIZATION ******
int ncols = 4; // number of columns
int nrows = 3; // number of rows
boolean right = true; // direction of sweep on horizontal axis
boolean top = true; // direction of sweep on vertical axis
int counter = 0; // number of positions explored
if (right) {
colIterator = 0;
}
else {
colIterator = ncols - 1;
}
if (top) {
rowIterator = 0;
}
else {
rowIterator = nrows - 1;
}
// ****** CONTINUATION CONDITION ******
while (counter != nrows*ncols) {
// ****** DO SOMETHING ******
System.out.println(rowIterator*ncols + colIterator);
// ****** PROGRESSION PHASE ******
counter++;
// Have we completed a row?
if ((counter % ncols) == 0) {
if (top) {
// We have to move up
rowIterator++;
}
else {
// we have to move down
rowIterator--;
}
if (right) {
colIterator = 0;
}
else {
colIterator = ncols - 1;
}
}
else {
// We have not yet completed a row
if (right) {
// We have to move right
colIterator++;
}
else {
// or left
colIterator--;
}
}
}
Note: this code has been tested with Groovy.
A bit of upper-level explanation: it works with one loop because in 2D, we can find a global metric of the advancement of the work we want to do (here this metric is the counter variable) and can use the metric to determine, at each iteration of the loop, if we have completed a row (or not) by using the modulus operation.
I don't think it is mathematically possible to generalize this algorithm to upper dimensions (i.e. above 2) with only one loop, because there will be no mathematical operator that will tell us if we have finished part of the work on one given dimension and should start working on the outter dimensions (here, the modulus tells us that we have to modify the rowIterator because we have reached a border of the grid, but in dimension 3 or above 3, what would be the mathematical operator to use?).
Good luck and please post what you find, it's an interesting challenge.

Going through a square matrix in an ever smaller spiral

What I want to do is an algorithm that goes through a matrix in a closing spiral pattern as follows:
1 | 2 | 3
---------
8 | 9 | 4
---------
7 | 6 | 5
What would be the simplest way to tackle this problem ?
My thoughts:
Corner or obstacle detection.
Have a programmatic way to go down vertically and in reverse.
Have a way to detect that an element has already been visited.
P.S: Not sure how to handle a case where the size is not a square or the width is an even number.
You don't need a visited concept for each cell, just a single variable to indicate how far you are.
Below is some (not extensively tested) Java code to do this.
It should be pretty readable.
// initialize
int w = 5, h = 7;
int[][] arr = new int[w][h];
// do the work
int count = 1;
for (int i = 0; count <= w*h; i++)
{
// go right
for (int x = i; x < w-i && count <= w*h; x++)
arr[x][i] = count++;
// go down
for (int y = i+1; y < h-i && count <= w*h; y++)
arr[w-i-1][y] = count++;
// go left
for (int x = w-2-i; x >= i && count <= w*h; x--)
arr[x][h-i-1] = count++;
// go up
for (int y = h-2-i; y > i && count <= w*h; y--)
arr[i][y] = count++;
}
Java.
Output:
1 2 3 4 5
20 21 22 23 6
19 32 33 24 7
18 31 34 25 8
17 30 35 26 9
16 29 28 27 10
15 14 13 12 11
For each cell, have a number that denotes how many empty/visited cells are in its immediate vertical and horizontal position (let's call it numVisitedAroundCell.) Also, have a boolean flag isVisited. Go through the cells and update numVisitedAroundCell (so the corner cells would have numVisitedAroundCell == 2 and the outer layer of cells that is not a corner would have numVisitedAroundCell == 1)
Go through the cells and find a corner cell, which would be a cell with numVisitedAroundCell == 2.
From there, either go vertically or horizontally, while marking each cell you pass as isVisited and incrementing the number of numVisitedAroundCell. Keep going down the path you choose until you hit a corner cell(when you hit this corner cell, numVisitedAroundCell should be 3), then find the next unvisited cell, and go down that route. If you keep doing this, I believe you will get the spiral that you wanted. Also, this should deal with cases where the width is even and if the size is not square.
Recursively, for no good reason:
Use four functions, named right(), down(), left(), and up().
The right() function counts along the top row of the matrix, and then
passes the remaining rows (all excluding the one it just filled in) to
down().
The down() function counts down the right edge of the matrix, and then
passes the remaining columns to left().
etc.
Recursion stops when a width or a height reaches zero.

Partitioning a no. N into M partitions

I'm trying a problem in which I have to partition a no. N into M partitions as many as possible.
Example:
N=1 M=3 , break 1 into 3 parts
0 0 1
0 1 0
1 0 0
N=3 M=2 , break 3 into 2 parts
2 1
1 2
3 0
0 3
N=4 M=4 , break 4 into 4 parts
0 0 0 4
0 0 4 0
0 4 0 0
4 0 0 0
0 0 1 3
0 1 0 3
0 1 3 0
.
.
.
and so on.
I did code a backtrack algo. which produce all the possible compositions step by step, but it chokes for some larger input.Because many compositions are same differing only in ordering of parts.I want to reduce that.Can anybody help in providing a more efficient method.
My method:
void backt(int* part,int pos,int n) //break N into M parts
{
if(pos==M-1)
{
part[pos]=n;
ppart(part); //print part array
return;
}
if(n==0)
{
part[pos]=0;
backt(part,pos+1,0);
return;
}
for(int i=0;i<=n;i++)
{
part[pos]=i;
backt(part,pos+1,n-i);
}
}
In my algo. n is N and it fill the array part[] for every possible partition of N.
What I want to know is once generating a composition I want to calculate how many times that composition will occur with different ordering.For ex: for N=1 ,M=3 ::: composition is only one : <0,0,1> ,but it occurs 3 times. Thats what I want to know for every possible unique composition.
for another example: N=4 M=4
composition <0 0 0 4> is being repeated 4 times. Similarly, for every unique composition I wanna know exactly how many times it will occur .
Looks like I'm also getting it by explaining here.Thinking.
Thanks.
You can convert an int to a partitioning as follows:
vector<int> part(int i, int n, int m)
{
int r = n; // r is num items remaining to be allocated
vector<int> result(m, 0); // m entries inited to 0
for (int j = 0; j < m-1; j++)
{
if (r == 0) // if none left stop
break;
int k = i % r; // mod out next bucket
i /= r; // divide out bucket
result[j] = k; // assign bucket
r -= k; // remove assigned items from remaining
}
result[m-1] = r; // put remainder in last bucket
return result;
}
So you can use this as follows:
for (int i = 0; true; i++)
{
vector<int> p = part(i, 3, 4);
if (i != 0 && p.back() == 3) // last part
break;
... // use p
};
It should be clear from this how to make an incremental version of part too.
A much simpler and mathematical approach:
This problem is equivalent to finding the co-efficient of x^N in the expression f(x) = (1+x+x^2+x^3+....+x^N)^M
f(x) = ((x^(N-1) - 1)/(x-1))^M
differentiate it M times(d^Nf(x)/dx^N) and the co-efficient will be (1/n!)*(d^Nf(x)/dx^N) at x = 0;
differentiation can be done using any numerical differentiation technique. So the complexity of the algorithm is O(N*complexity_of_differentiation)..

Resources