• 面试题:Java回形数组


    最近遇到一个面试题。

    给定一个数字n,输出一个n阶矩阵。矩阵中的元素为1到n²。按回形排列
    eg1 :

    输入:n=2
    输出:
    1 2
    4 3

    eg2:

    输入:n=3
    输出:
    1 2 3
    8 9 4
    7 6 5

    思路:

    这个题属于现实中遇到很简单,但是程序实现还是有些难度的问题。
    面试的时候面试官让我手写出这个问题的解法,无奈最后实在没写出来。纸上写代码太难了。
    这个问题其实需要分成三个层次去看。
    第一层看出来,此问题需要一个二维数组解决
    第二层看出来,此问题一个有四种操作数组的情况
    第三层看出来,此问题可以按层次操作。
    明白这三层思路,那就能解决问题了。但是还是有几个边界问题需要处理

    1. 如何划分四种操作的操作范围

    这个问题其实看你的习惯,我这里是按平均分配的原则分配给了四次操作。每次操作处理n-1-当前层数
    image.png

    2. n为奇数的时候,最内层只有一个元素。此时按下面方法无法被处理。因此如果n为奇数时直接将最内层的填充为n*n

    代码

    public class Solution {
        /**
         * 二维数组输出工具
         *
         * @param arr    二维数据
         * @param length 补齐长度
         */
        static void print(int[][] arr, int length) {
            for (int[] ints : arr) {
                for (int anInt : ints) {
                    System.out.print(getLengthSpace(anInt, length));
                }
                System.out.println();
            }
        }
    
        /**
         * 补齐空格工具类
         *
         * @param num    元素
         * @param length 补齐的长度
         * @return 补齐之后的元素
         */
        static String getLengthSpace(int num, int length) {
            StringBuilder result = new StringBuilder(String.valueOf(num));
            int size = length - result.length() + 1;
            for (int i = 0; i < size; i++) {
                result.append(" ");
            }
            return result.toString();
        }
    
        public static void main(String[] args) {
            print(fun(100), 5);
        }
    
        /**
         * 回形数组构建
         *
         * @param n 阶数
         * @return n阶数组
         */
        static int[][] fun(int n) {
            int[][] arr = new int[n][n];
            int start = 1;
            //当前构建的层数,默认为0
            int layer = 0;
            //如果n为偶数则遍历n/2此,若n为奇数则需要遍历n/2+1次。
            for (int i = 0; i < (n / 2 + n % 2); i++) {
                //水平向右填充
                for (int first = layer; first < n - 1 - layer; first++) {
                    arr[layer][first] = start++;
                }
                //垂直向下填充
                for (int second = layer; second < n - 1 - layer; second++) {
                    arr[second][n - layer - 1] = start++;
                }
                //水平向左填充
                for (int third = n - layer - 1; third > layer; third--) {
                    arr[n - layer - 1][third] = start++;
                }
                //垂直向上填充
                for (int forth = n - layer - 1; forth > layer; forth--) {
                    arr[forth][layer] = start++;
                }
                //进行下一层遍历
                ++layer;
            }
            //n为奇数的时候,数组最中间的元素无法被填写。因此手动填充为n*n
            if (n % 2 != 0) {
                int mid = n >> 1;
                arr[mid][mid] = n * n;
            }
            return arr;
        }
    }
    
    
  • 相关阅读:
    【洛谷P1948】[USACO08JAN]电话线
    【洛谷P1967】[NOIP2013]货车运输
    【题解】洛谷P2926 [USACO08DEC]拍头Patting Heads
    【题解】洛谷P1495 曹冲养猪 (中国剩余定理)
    【题解】POJ1845 Sumdiv(乘法逆元+约数和)
    【题解】P1516 青蛙的约会(Exgcd)
    【数论】同余问题
    DP Cleaning Up 打扫卫生
    set+链表 【POJ Challenge】生日礼物
    并查集 [Scoi2010]游戏
  • 原文地址:https://www.cnblogs.com/rever/p/13398771.html
Copyright © 2020-2023  润新知