Java数组算法——“回形数”或“回形矩阵” (数组元素的赋值类别算法)

介绍:

从键盘输入一个整数(1~20) 

则以该数字为矩阵的大小,把1,2,3…n*n 的数字按照顺时针螺旋的形式填入其中。

例如: 输入数字2,则程序输出:

1    2    
4    3    

输入数字3,则程序输出: 

1    2    3    
8    9    4    
7    6    5

输入数字4, 则程序输出: 

 1       2       3       4    
12     13     14      5    
11     16     15      6    
10      9       8       7    

图示:

 

代码:

写法一(方向思路):

public class Main {
    private static final int RIGHT = 1;  //向右
    private static final int DOWN = 2;   //向下
    private static final int LEFT = 3;   //向左
    private static final int ON = 4;     //向上
    /*
     * k = 1:向右 k = 2:向下 k = 3:向左 k = 4:向上
     */

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入一个数字");
        int num = scanner.nextInt();
        int[][] huiXingShu = new int[num][num];

        int count = num * num; //s表示该矩阵的总数目

        int k = RIGHT; //k变量表示往哪个方向赋值  初始化从向右开始
        int i = 0, j = 0; //i表示数组的纵坐标  j表示数组的横坐标
        for (int m = 1; m <= count; m++) {  //循环的次数刚好是矩阵的总数目
            if (k == RIGHT) {   //向右    赋值限制条件:如果横坐标小于输入的矩阵纵横数并且值是默认值0就给它赋值
                if (j < num && huiXingShu[i][j] == 0) {
                    huiXingShu[i][j++] = m;
                } else {    //如果不是
                    k = DOWN;  //表示改变方向赋值  向下
                    i++;    //每次方向赋值完 要换一行方便下个判断赋值 所以i自增1 保证下次循环i下标是正确的
                    j--;    //每次方向赋值完 要帮上面j++多运行的一次自减1 保证下次循环j下标是正确的
                    m--;    //每次方向赋值完 进入else语句都要自减1 保证下次循环m的赋值数是正确的
                }
            } else if (k == DOWN) {    //向下   以下同理
                if (i < num && huiXingShu[i][j] == 0) { 
                    huiXingShu[i++][j] = m;
                } else {
                    k = LEFT;
                    i--;
                    j--;
                    m--;
                }
            } else if (k == LEFT) {    //向左
                if (j >= 0 && huiXingShu[i][j] == 0) {
                    huiXingShu[i][j--] = m;
                } else {
                    k = ON;
                    i--;
                    j++;
                    m--;
                }
            } else if (k == ON) {    //向上
                if (i >= 0 && huiXingShu[i][j] == 0) {
                    huiXingShu[i--][j] = m;
                } else {
                    k = RIGHT;
                    i++;
                    j++;
                    m--;
                }
            }
        }

        // 遍历
        for (int[] anArr : huiXingShu) {
            for (int anAnArr : anArr) {
                System.out.print(anAnArr + "\t");
            }
            System.out.println();
        }
    }
}

写法二(下标思路):

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入一个数字");
        int num = scanner.nextInt();
        int[][] huiXingShu = new int[num][num];

        int count = 0; // 要显示的数据
        int maxX = num - 1; // x横轴的最大下标
        int maxY = num - 1; // Y纵轴的最大下标
        int minX = 0; // x横轴的最小下标
        int minY = 0; // Y纵轴的最小下标
        while (minX <= maxX) {  //直到X横轴线最小下标比最大下标还大时就退出循环 说明已经把值赋到最后一个了
            for (int x = minX; x <= maxX; x++) {    //向右 从最小到最大下标递增
                huiXingShu[minY][x] = ++count;  //必须++count 不然count++第一次会赋值为0
            }
            minY++;     //说明Y纵轴的最小下标+1 向右已经赋值完一行了
            for (int y = minY; y <= maxY; y++) {    //向下 从最小到最大下标递增
                huiXingShu[y][maxX] = ++count;
            }
            maxX--;     //以上同理不再赘述
            for (int x = maxX; x >= minX; x--) {    //向左 从最小到最大下标递减
                huiXingShu[maxY][x] = ++count;
            }
            maxY--;
            for (int y = maxY; y >= minY; y--) {    //向上 从最小到最大下标递减
                huiXingShu[y][minX] = ++count;
            }
            minX++;
        }

        // 遍历
        for (int[] anhuiXingShu : huiXingShu) {
            for (int anAnhuiXingShu : anhuiXingShu) {
                System.out.print(anAnhuiXingShu + "\t");
            }
            System.out.println();
        }
    }
}

 

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现稀疏矩阵的快速转置算法可以有多种方法,其中一种常用的方法是使用三元组(也称为三元组表)来表示稀疏矩阵。三元组表是一种用于表示稀疏矩阵的数据结构,它将矩阵中所有非零元素的行、列和值存储在一个数组中。 下面是使用三元组表实现稀疏矩阵的快速转置算法Java代码: ```java public static void transpose(int[][] matrix) { // 计算矩阵的行数和列数 int numRows = matrix.length; int numCols = matrix[0].length; // 统计矩阵中非零元素的个数 int numNonZeros = 0; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numCols; j++) { if (matrix[i][j] != 0) { numNonZeros++; } } } // 创建三元组表 int[][] triplets = new int[numNonZeros][3]; int k = 0; for (int i = 0; i < numRows; i++) { for (int j = 0; j < numCols; j++) { if (matrix[i][j] != 0) { triplets[k][0] = i; triplets[k][1] = j; triplets[k][2] = matrix[i][j]; k++; } } } // 对三元组表进行快速转置 int[][] transposedTriplets = new int[numNonZeros][3]; int[] colCounts = new int[numCols]; for (int i = 0; i < numNonZeros; i++) { colCounts[triplets[i][1]]++; } int[] colStarts = new int[numCols]; colStarts[0] = 0; for (int i = 1; i < numCols; i++) { colStarts[i] = colStarts[i - 1] + colCounts[i - 1]; } for (int i = 0; i < numNonZeros; i++) { int j = colStarts[triplets[i][1]]; transposedTriplets[j][0] = triplets[i][1]; transposedTriplets[j][1] = triplets[i][0]; transposedTriplets[j][2] = triplets[i][2]; colStarts[triplets[i][1]]++; } // 将转置后的三元组表转换稀疏矩阵 int[][] transposedMatrix = new int[numCols][numRows]; for (int i = 0; i < numNonZeros; i++) { transposedMatrix[transposedTriplets[i][0]][transposedTriplets[i][1]] = transposedTriplets[i][2]; } // 将转置后的矩阵赋值给原矩阵 for (int i = 0; i < numRows; i++) { for (int j = 0; j < numCols; j++) { matrix[i][j] = transposedMatrix[i][j]; } } } ``` 该算法的时间复杂度为O(N+NZ),其中N为矩阵的大小,NZ为矩阵中非零元素的个数。该算法的空间复杂度为O(NZ)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值