剑指offer---1、顺时针打印矩阵

剑指offer---1、顺时针打印矩阵

一、总结

一句话总结:

谋而后动+多做:还是要谋而后动,但是怎么谋而后动,很有学问,做好的方式就是多做
问题就这些问题:解决了就好了,比如php多维数组
面试的时候最重要的是刷编程题:因为一定会考到:那些人也是通过编程题知道你的编程水平的

 

1、自己的思路的不足之处?

1、矩形的编程表示:没有想到正方形(或矩形)在编程中只用 左下角和右下角 两个点即可表示
2、打印结束条件:因为正方形的表示没想好,也没想好 打印结束的判断条件:
3、不必用 访问 辅助数组:因为确定好两点表示矩阵的话就不必访问数组
int left = 0, top = 0, right = col - 1, bottom = row - 1;
while (left <= right && top <= bottom)

自己的思路是怎样的
必然四种操作:
右、下、左、上
每种操作,必然都有起点和终点
这四种操作的顺序必为:右、下、左、上
用变量记录这四种操作的起点和终点

初始
right[1,每一行的长度]
down[1,每一列的长度]
left[每一行的长度,1]
up[每一列的长度,1]

访问之后,起点和终点都加1
结束条件是 起点大于终点

每个点记录被访问了没有,没有被访问的话我们才访问它


伪代码
1、复制数组:做是否访问的数组
2、按 右、下、左、上 的顺序访问数组

 

 

2、正方形(或矩形)在编程中怎么表示?

四个变量:记录左下角这个点和记录右下角这个点即可
完全不需要设置四个方向上的起点和终点:因为行变化了,你不好取数据
int left = 0, top = 0, right = col - 1, bottom = row - 1;

 

 

3、php如何将数组中的元素全置为1?

空数组+两重foreach赋值的方式
$matrix1=[];
foreach($matrix as $key1=>$val1){
  foreach($val1 as $key2=>$val2){
      $matrix1[$key1][$key2]=1;
  }
}

 

 

4、php中的2维数组是怎么存的?

中括号里面套中括号:数组中套数组
Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 4
        )

    [1] => Array
        (
            [0] => 5
            [1] => 6
            [2] => 7
            [3] => 8
        )

    [2] => Array
        (
            [0] => 9
            [1] => 10
            [2] => 11
            [3] => 12
        )

    [3] => Array
        (
            [0] => 13
            [1] => 14
            [2] => 15
            [3] => 16
        )

)

 

 

 

5、php中的多维数组怎么定义?

中括号:$matrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]];

 

6、php如何遍历多维数组?

两重foreach
$a=array('fruits'=>array('a'=>'orange','b'=>'grape','c'=>'apple'),
     'numbers'=>array(1,2,3,4,5,6),
     'holes'=>array('first',5=>'second','third')
 );

foreach($a as $v ){
    foreach($v as $value ){
        echo $value,"<br/>";
    }
}

 

 

7、如何求二维矩阵行和列元素的数量(元素:element)?

列元素的数量:求这个矩阵中的元素的个数:$lie_element_num=count($matrix);
行元素的数量:求第一行的元素个数:$hang_element_num=count($matrix[0]);

 

8、我设置 右、下、左、上 四个方向上的起点和终点 这样的方式的不好之处是什么?

1、比如:这样不好从第一次右打印过渡到第二次右打印,因为行变化了,你不好取数据
2、变量的冗余:这里面很多的方向的起点终点都是冗余的

 

 

9、打印矩阵的时候的判断条件怎么确定?

1、int left = 0, top = 0, right = col - 1, bottom = row - 1;// 定义四个关键变量,表示左上和右下的打印范围
2、左不大于右,上不大于下:while (left <= right && top <= bottom)

 

10、顺时针打印矩阵 参考代码?

思想:用左上和右下的坐标定位出一次要旋转打印的数据,一次旋转打印结束后,往对角分别前进和后退一个单位。
/*
    思想,用左上和右下的坐标定位出一次要旋转打印的数据,一次旋转打印结束后,往对角分别前进和后退一个单位。
    提交代码时,主要的问题出在没有控制好后两个for循环,需要加入条件判断,防止出现单行或者单列的情况。
 */
class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        int row = matrix.size();
        int col = matrix[0].size();
        vector<int> res;
         
        // 输入的二维数组非法,返回空的数组
        if (row == 0 || col == 0)  return res;
         
        // 定义四个关键变量,表示左上和右下的打印范围
        int left = 0, top = 0, right = col - 1, bottom = row - 1;
        while (left <= right && top <= bottom)
        {
            // left to right
            for (int i = left; i <= right; ++i)  res.push_back(matrix[top][i]);
            // top to bottom
            for (int i = top + 1; i <= bottom; ++i)  res.push_back(matrix[i][right]);
            // right to left
            if (top != bottom)
            for (int i = right - 1; i >= left; --i)  res.push_back(matrix[bottom][i]);
            // bottom to top
            if (left != right)
            for (int i = bottom - 1; i > top; --i)  res.push_back(matrix[i][left]);
            left++,top++,right--,bottom--;
        }
        return res;
    }
};

 

 

11、如何解决打印的是矩形而不是正方形的问题?

1、对(top != bottom)和(left != right)进行特判:避免重复输出
2、访问 辅助数组
if (top != bottom)
for (int i = right - 1; i >= left; --i)  res.push_back(matrix[bottom][i]);
// bottom to top
if (left != right)
for (int i = bottom - 1; i > top; --i)  res.push_back(matrix[i][left]);

 

12、注意在线敲代码的函数里面是return,比如牛客网?

函数里面是return,而不是打印变量

 

13、矩形的问题要注意的是什么?

矩形不是正方形

 

 

二、内容在总结中

1、题目描述

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


题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下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.

 

 

2、代码

/*
    思想,用左上和右下的坐标定位出一次要旋转打印的数据,一次旋转打印结束后,往对角分别前进和后退一个单位。
    提交代码时,主要的问题出在没有控制好后两个for循环,需要加入条件判断,防止出现单行或者单列的情况。
 */
class Solution {
public:
    vector<int> printMatrix(vector<vector<int> > matrix) {
        int row = matrix.size();
        int col = matrix[0].size();
        vector<int> res;
         
        // 输入的二维数组非法,返回空的数组
        if (row == 0 || col == 0)  return res;
         
        // 定义四个关键变量,表示左上和右下的打印范围
        int left = 0, top = 0, right = col - 1, bottom = row - 1;
        while (left <= right && top <= bottom)
        {
            // left to right
            for (int i = left; i <= right; ++i)  res.push_back(matrix[top][i]);
            // top to bottom
            for (int i = top + 1; i <= bottom; ++i)  res.push_back(matrix[i][right]);
            // right to left
            if (top != bottom)
            for (int i = right - 1; i >= left; --i)  res.push_back(matrix[bottom][i]);
            // bottom to top
            if (left != right)
            for (int i = bottom - 1; i > top; --i)  res.push_back(matrix[i][left]);
            left++,top++,right--,bottom--;
        }
        return res;
    }
};

 

 

php代码

<?php

//用访问数组解决:不是正方形而是矩形的问题
function printMatrix($matrix)
{
    $vis=$matrix;
    foreach ($matrix as $k=>$v){
        foreach ($v as $k1=>$v1){
            $vis[$k][$k1]=-1;
        }
    }
    // write code here
    $hang_ele_num=count($matrix[0]);
    $lie_ele_num=count($matrix);
    $a_x=0;$a_y=0;$b_x=$hang_ele_num-1;$b_y=$lie_ele_num-1;
    $ans=[];
    while($a_x<=$b_x&&$a_y<=$b_y){
        //依次打印右下左上
        for($i=$a_x;$i<=$b_x;$i++){
            if($vis[$a_y][$i]==-1){
                $ans[]=$matrix[$a_y][$i];
                $vis[$a_y][$i]=1;
            }
        }

        for($i=$a_y+1;$i<=$b_y;$i++){
            if($vis[$i][$b_x]==-1){
                $ans[]=$matrix[$i][$b_x];
                $vis[$i][$b_x]=1;
            }

        }

        for($i=$b_x-1;$i>=$a_x;$i--){
            if($vis[$b_y][$i]==-1){
                $ans[]=$matrix[$b_y][$i];
                $vis[$b_y][$i]=1;
            }
        }
        for($i=$b_y-1;$i>=$a_y+1;$i--){
            if($vis[$i][$a_x]==-1){
                $ans[]=$matrix[$i][$a_x];
                $vis[$i][$a_x]=1;
            }
        }
        $a_x++;$a_y++;$b_x--;$b_y--;
    }
    return $ans;
}

 

 

 

转载于:https://www.cnblogs.com/Renyi-Fan/p/10995678.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值