剑指offer:顺时针打印矩阵
- 题目JZ17:顺时针打印矩阵
- 题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210225001409432.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxOTMyMDQ4,size_16,color_FFFFFF,t_70)
算法
蚂蚁对象
- 蚂蚁有三个向量:position,direction,next_position。分别表示了蚂蚁当前位置,蚂蚁方向,蚂蚁下一个位置。 这三个向量的关系是蚂蚁根据选择的方向,确定下一个位置。然后,下一位置决定了当前位置的更新情况。
蚂蚁爬地图的策略
- 蚂蚁策略是:蚂蚁按照【右->下->左->上】的顺序来确定自己的方向。蚂蚁在移动过程中,会根据自己当前方向,来确定下一位置。然后可以根据下一位置是否是墙来选择是否更新当前位置和当前方向,这里的策略是:如果下一位置是墙,那么不更新当前位置,应该更新当前方向;如果下一位置不是墙,要进行的操作是:不更新当前方向,应该将当前位置的值进入容器,然后标记当前位置的值,最后更新当前位置。最后蚂蚁爬地图结束的策略是:当蚂蚁当前位置四周都是墙的时候就结束了。
- 这里通过核心代码分析一下上述过程。
首先介绍一下代码中的一些函数和数据结构:
①函数:find_direction(),会根据蚂蚁某个确定的方向搜索下一个位置是否碰到墙,如果碰到墙会返回 2,反之返回 1;environment()函数会检查蚂蚁四周是否都是墙,如果四周都是墙会返回 ture,反之返回false;
②数据结构:directions矩阵,directions保存了【右->下->左->上】四个方向向量;map保存了蚂蚁需要爬的地图;arr是一个记录蚂蚁经过路径的ArrayList容器;ants是一只蚂蚁。 - 了解了相关函数后,就可以介绍下面代码了。
首先通过一个外层while循环,让蚂蚁需要更新方向的时候,应该按照【右->下->左->上】的策略来循环更新方向。
蚂蚁先在for循环中选择一个方向,
然后进入内层while循环中,执行find_direction()函数,根据所选择的方向来确定是否在这个方向上继续搜索。
然后find_direction()函数的返回值不满足条件时,也就是不再该方向搜索会跳出内层while循环,从而for循环迭代下一个方向。
当四个方向都选择完毕,跳出for循环,准备来第二次的时候,此时应该通过environment()函数检查是否周围都是墙,以判断蚂蚁是否再爬一圈。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210225212519862.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxOTMyMDQ4,size_16,color_FFFFFF,t_70)
代码:
import java.util.*;
class Ants{
public static final int [] RIGHT = {1, 0, 0, 0};
public static final int [] DOWN = {0, -1, 0, 0};
public static final int [] LEFT = {0, 0, -1, 0};
public static final int [] UP = {0, 0, 0, 1};
private int [] position;
private int [] direction;
private int [] next_position;
public Ants(int [] position, int [] direction) {
this.position = position;
this.next_position = position.clone();
this.direction = direction;
}
public void set_position(int [] next_position) {
this.position = next_position.clone();
}
public int [] get_position() {
return this.position;
}
public void set_next_position(int [] direction) {
this.next_position = this.position.clone();
if(direction[0] == Ants.RIGHT[0]) {
this.next_position[1] = this.position[1] + Ants.RIGHT[0];
}else if(direction[1] == Ants.DOWN[1]) {
this.next_position[0] = this.position[0] - Ants.DOWN[1];
}else if(direction[2] == Ants.LEFT[2]) {
this.next_position[1] = this.position[1] + Ants.LEFT[2];
}else if(direction[3] == Ants.UP[3]){
this.next_position[0] = this.position[0] - Ants.UP[3];
}
}
public int [] get_next_positon() {
return this.next_position;
}
public void set_direction(int [] direction) {
this.direction = direction;
this.set_next_position(this.direction);
}
public int [] getD() {
return this.direction;
}
}
public class problem1{
public static final int [] INIT_POSITION = {1, 1};
public static final int [] INIT_DIRECTION = {0, 0, 0, 0};
public static final int WALL = -1;
public static final int [][] MATRIX= {{1,2},{3,4}};
public static final int MATRIX_X_LEN = MATRIX.length;
public static final int MATRIX_Y_LEN = MATRIX[0].length;
public static final int NO_WALL = 1;
public static final int YES_WALL = 2;
public static final int INCREMENT = 2;
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> arr = new ArrayList<>();
int [][] map = initMap(matrix);
int [] position= INIT_POSITION;
int [] direction = INIT_DIRECTION;
Ants ants = new Ants(position, direction);
int [][] directions = {Ants.RIGHT, Ants.DOWN, Ants.LEFT, Ants.UP};
int [] next_position = INIT_POSITION;
while(true) {
for (int i = 0; i < directions.length; i++) {
while(find_direction(directions[i], ants, map, arr) == NO_WALL) {
}
}
if(environment(directions, ants, map)) {
int position_x = ants.get_position()[0];
int position_y = ants.get_position()[1];
arr.add(map[position_x][position_y]);
break;
}
}
return arr;
}
public int find_direction(int [] direction, Ants ants, int [][] map, ArrayList<Integer> arr) {
if (!isWall(direction, ants, map)) {
int position_x = ants.get_position()[0];
int position_y = ants.get_position()[1];
int [] next_position = ants.get_next_positon();
arr.add(map[position_x][position_y]);
map[position_x][position_y] = WALL;
ants.set_position(next_position);
printMap(map);
return NO_WALL;
} else {
return YES_WALL;
}
}
public boolean environment(int [][] directions, Ants ants, int [][] map) {
boolean flag = true;
for(int i=0; i< directions.length; i++) {
if(!isWall(directions[i], ants, map)) {
flag = false;
break;
}
}
return flag;
}
public boolean isWall(int [] direction, Ants ants, int [][] matrix) {
ants.set_direction(direction);
int next_position_x = ants.get_next_positon()[0];
int next_position_y = ants.get_next_positon()[1];
if(matrix[next_position_x][next_position_y] == WALL) {
return true;
}else {
return false;
}
}
public int [][] initMap(int [][] matrix){
int[][] map = new int[MATRIX_X_LEN + INCREMENT][MATRIX_Y_LEN + INCREMENT];
for (int i = 0; i < map[0].length; i++) {
map[0][i] = WALL;
map[map.length - 1][i] = WALL;
}
for(int j = 0; j < map.length; j++) {
map[j][0] = WALL;
map[j][map[0].length-1] = WALL;
}
for(int i=0; i< MATRIX_X_LEN; i++) {
for(int j=0; j< MATRIX_Y_LEN; j++) {
map[i+1][j+1] = matrix[i][j];
}
}
return map;
}
public void printMap(int [][] matrix) {
System.out.println("map 过程:");
for(int i=0; i< MATRIX_X_LEN+INCREMENT; i++) {
for(int j=0; j< MATRIX_Y_LEN+INCREMENT; j++) {
if(matrix[i][j]>0 && matrix [i][j]<10) {
System.out.print(matrix[i][j]+" ");
}else {
System.out.print(matrix[i][j]+" ");
}
}
System.out.println("");
}
System.out.println("-------------------");
}
public void printArrayList(ArrayList<Integer> arr) {
System.out.println("容器值:");
for(int i=0; i< arr.size(); i++) {
System.out.print(arr.get(i) + " ");
}
}
public static void main(String args[]) {
problem1 p = new problem1();
p.printMap(p.initMap(MATRIX));
p.printArrayList(p.printMatrix(MATRIX));
}
}