1.6 Given an image represented by an NxN matrix, where each pixel in the image is 4 bytes, write a method to rotate the image by 90 degrees. Can you do this in place?
这个题看到4 bytes的时候以为要考移植性,不过既然用java,就不考虑了。
RotateImage1()使用一个缓冲区,实现很简单,找到(i,j)对应(j, n-1-i)这个关系就可以了。
RotateImage2()是RotateImage1()的in place版本,读一行写一列。(Updated: in place应该指的是不开辟新数组的意思,以前理解成on-line了,应该是错的)
RotateImage3()比前两个函数复杂一些,结果书里面也是这个方法。实现了RotateImage1()之后就在考虑能不能不使用缓冲区。如果不使用的话,显然按行或者按列来处理的方法就不可行了,那么就从交换点入手。画了几个矩阵,然后总结出来一个矩阵元素的“迁移图”。
package Question1_6;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class Question1_6
{
public static void main(String[] args) throws FileNotFoundException
{
int[][] image = new int[][]{{1,2,3,4,5}, {5,6,7,8,9}, {9,0,1,2,5}, {3,4,5,6,7}, {3,2,1,4,6}};
Question1_6 q = new Question1_6();
System.out.println("Before rotating:");
q.printArray(image, 5);
System.out.println("After rotating:");
image = q.RotateImage1(image, 5);
q.printArray(image, 5);
System.out.println("After rotating:");
//image = q.RotateImage2(5);
q.printArray(image, 5);
System.out.println("After rotating:");
q.RotateImage3(image, 5);
q.printArray(image, 5);
}
public int[][] RotateImage1(int[][] image, int n)
{
// rotate using an additional buffer
int[][] imageClone = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
// it is easy to generate the relationship between image and the rotated image
imageClone[j][n-1-i] = image[i][j];
}
return imageClone;
}
public int[][] RotateImage2(int n) throws FileNotFoundException
{
// rotate in place
// Scanner scanner = new Scanner(new FileReader("Matrix.txt"));
int[][] imageClone = new int[n][n];
int line = 0;
// rotate line by line
while (scanner.hasNext())
{
String[] strings = scanner.next().split(",");
for (int i = 0; i < strings.length; i++)
imageClone[i][n-1-line] = Integer.parseInt(strings[i]);
line++;
}
return imageClone;
}
public void RotateImage3(int[][] image, int n)
{
// rotate without using an additional buffer
// For a matrix of n*n, it has n/2 cycles (when n is odd, the innermost
// single number is not regarded as a cycle)
for (int cycle = 0; cycle < n/2; cycle++)
{
// For a specific cycle, we must swap (n-1-2*cycle) times
// When cycle increases by 1, the swap times will decrease by 2
for (int i = 0; i < n - 1 - 2 * cycle; i++)
{
// save left top
int temp = image[cycle][cycle+i];
// left bottom -> left top
image[cycle][cycle+i] = image[n-1-cycle-i][cycle];
// right bottom -> left bottom
image[n-1-cycle-i][cycle] = image[n-1-cycle][n-1-cycle-i];
// right top -> right bottom
image[n-1-cycle][n-1-cycle-i] = image[cycle+i][n-1-cycle];
// left -> right top
image[cycle+i][n-1-cycle] = temp;
}
}
}
private void printArray(int[][] image, int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
System.out.print(image[i][j] + " ");
System.out.println();
}
}
}