《剑指offer》面试题20 顺时针打印矩阵 Java版

我的方法:遇到这种题最好在纸上画一画打印路线。我利用了4个标志left、top、right、bottom,表示当前需要打印的左界、上届、右界和下界,换句话说这些界线之外的已经打印了,如此一来判断结束的标准也很清晰,top>bottom或者left>right就表示已经没有需要打印的空间。和第14题中确定结束条件类似,明确下标的含义,就能很快判断结束条件。

    public void myPrint(int[][] a){
        if(a == null || a.length == 0 || (a.length == 1 && a[0].length == 0)){
            return;
        }
        int left = 0;
        int right = a[0].length -1;
        int top = 0;
        int bottom = a.length - 1;
        //用于改变方向,分别代表  从左向右打印,从上往下打印,从又往左打印,从下往上打印。
        int[] orientations = new int[]{0, 1, 2, 3};
        int count = 0;
        while(left <= right && top <= bottom){
             //按顺序改变方向
            switch (orientations[count%orientations.length]) {
            case 0:
                //从左向右打印一行,打印完后上界下移
                for(int i=left; i<=right; i++){
                    System.out.print(a[top][i]);
                }
                top++;
                count++;
                break;
            case 1:
                //从上到下打印一列,打印完后右界左移
                for(int i=top; i<=bottom; i++){
                    System.out.print(a[i][right]);
                }
                right--;
                count++;
                break;
            case 2:
                //从右到左打印一行,打印完后下界上移
                for(int i=right; i>=left; i--){
                    System.out.print(a[bottom][i]);
                }
                bottom--;
                count++;
                break;
            case 3:
                //从下到上打印一列,打印完后左界右移
                for(int i=bottom; i>=top; i--){
                    System.out.print(a[i][left]);
                }
                left++;
                count++;
                break;
            default:
                break;
            }
        }
    }

书中方法:书中的思路是一圈一圈向内打印,既然这样就要找到每一圈的起点和打印的圈。假设我们用count表示已经打印的圈数。起点就是(count, count);打印的圈是一个矩形条框,矩形可以由一条对角线确定,我们找到矩形条框右下角的点,就能由这个点和起点确定一个需要打印的圈(矩形框)。只要有起点的空间,就继续打印

    public void myPrint2(int[][] a){
        if(a == null || a.length == 0 || (a.length == 1 && a[0].length == 0)){
            return;
        }
        int count = 0;
        //打印了count次后,如果还留有下一次打印的起始点的位置,继续打印
        while(a.length - 2*count > 0 && a[0].length - 2*count > 0){
            printRound(a, count);
            count++;
        }
    }

打印的范围确定了,剩下就是按顺时针打印每一个圈。

    private void printRound(int[][] a, int count){
        int endX = a[0].length - 1 - count;
        int endY = a.length - 1 - count;
        int start = count;
        //无论如何第一行都需要打印
        for(int i=start; i<=endX; i++){
            System.out.print(a[start][i]);
        }
        //如果不止一行
        if(start < endY){
            for(int i=start+1; i<=endY; i++){
                System.out.print(a[i][endX]);
            }
        }
        if(start < endX && start < endY){
            for(int i=endX-1; i>=start; i--){
                System.out.print(a[endY][i]);
            }
        }
        if(start < endX && start < endY-1){
            for(int i=endY-1; i>start; i--){
                System.out.print(a[i][start]);
            }
        }
    }

原文地址:https://www.cnblogs.com/czjk/p/11629815.html

时间: 2024-07-28 13:43:43

《剑指offer》面试题20 顺时针打印矩阵 Java版的相关文章

【剑指offer】题目20 顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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. 思路: 关键注意①每一圈中四条边的边界,要每一次都打印到这一条边的末尾.右边的策略是错的,因为在只有一行一列时每一条边都判定该元素是下一条边的,导致错误.                       ②下面的边和左边

剑指offer——面试题17:打印从1到最大的n位数

用字符串模拟加法: 1 #include"iostream" 2 #include"string.h" 3 using namespace std; 4 5 bool AddOne(char *number,int n); 6 void PrintNumber(char *number,int n); 7 8 void Print1ToN(int n) 9 { 10 if(n<=0) 11 return; 12 char *number=new char[n+

剑指offer——面试题20:表示数值的字符串

1 #include"iostream" 2 using namespace std; 3 4 bool IsInt(const char **str); 5 bool IsUnsignInt(const char **str); 6 7 bool IsNumeric(const char* str) 8 { 9 if(str==nullptr) 10 return false; 11 bool flagNumeric=IsInt(&str);//二阶指针才能保留更改 12 1

剑指offer[面试题17:打印从1到最大的n位数]

题目:输入数字n,按顺序打印出从1到最大的n位十进制数.比如输入3,则打印出1.2.3一直到最大的三位数999. 思路: 隐藏考点:当输入的n很大时,用整型(int)或者长整型(long int)求最大的n位数都会溢出.也就是需要考虑大数问题. 用递归实现全排列,数字(用字符串容器装)的每一位都是0~9中的一个数,然后设置下一位.递归结束的条件是已经设置了数字的最后一位. class Solution { public: void PrintMaxOfDigits(int n){ if (n <

【剑指offer】面试题 29. 顺时针打印矩阵

面试题 29. 顺时针打印矩阵 题目描述 题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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. 解答过程 下图的矩阵顺时针打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 代码实现 import java.util.

二叉树层次遍历(剑指Offer面试题32:从上到下打印二叉树)

图1所示为二叉树的层次遍历,即按照箭头所指方向,按照1.2.3的层次顺序,对二叉树每个节点进行访问 (此图反映的是自左至右的层次遍历,自右至左的方式类似). 要进行层次遍历,需要建立一个队列.先将二叉树头节点入队列,然后出队列,访问该节点, 如果它有左子树,则将左子树的根结点入队:如果它有右子树,则将右子树的根结点入队.然后出队列,对出队节点访问, 如此反复直到队列为空为止. 1 import java.util.*; 2 class TreeNode 3 { 4 int val; 5 Tree

剑指offer面试题29:数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过数组长度的一般,请找出这个数字,例如输入一个长度为9的数组(1,2,3,2,2,2,5,4,2,).由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 个人第一眼想法是通过一个sort函数,再判断中间那数出现次数,只要出现多于n/2,就直接输出. 一般来说,最为直观的算法面试官都不会满意,那么有没有更优的算法呢? 这种算法是受快速排序算法的启发.在随机快速排序算法中,我们现在数组中随机选择一个数字,然后调整数组中数字的顺序,使得比选中的数字小的数字

【剑指Offer面试题】二维数组中的查找

下决心AC所有剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有好处的.加油~ 二维数组中的查找 时间限制:1 秒内存限制:32 兆 特殊判题:否提交:19005解决:3642 题目描述: 在一个

【剑指Offer面试题】九度OJ1384:二维数组中的查找

下决心AC全部剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有优点的.加油~ 题目链接地址: http://ac.jobdu.com/problem.php?pid=1384 二维数组中的查找