• 《剑指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]);
    			}
    		}
    	}
    
  • 相关阅读:
    uni-app开发经验分享四: 实现文字复制到选择器中
    uni-app开发经验分享三: Vuex实现登录和用户信息留存
    uni-app 开发随笔(踩坑记录)
    uni-app开发经验分享二: uni-app生命周期记录
    uni-app开发经验分享一: 多页面传值的三种解决方法
    JS复习笔记一:冒泡排序和二叉树列
    jQ实现图片无缝轮播
    canvas星空背景特效+CSS旋转相册学习
    CSS响应式布局学习笔记(多种方法解决响应式问题)
    LeetCode 76. 最小覆盖子串
  • 原文地址:https://www.cnblogs.com/czjk/p/11629815.html
Copyright © 2020-2023  润新知