4. tag数组和矩阵-lt.54-螺旋矩阵 + lt.59-螺旋矩阵II + lt.74-搜索二维矩阵 + 剑指Offer.29-顺时针打印矩阵 (待补充完善)

数组和矩阵结合的问题

lt.54 螺旋矩阵

[案例需求]
4. tag数组和矩阵-lt.54-螺旋矩阵 + lt.59-螺旋矩阵II + lt.74-搜索二维矩阵 + 剑指Offer.29-顺时针打印矩阵 (待补充完善)4. tag数组和矩阵-lt.54-螺旋矩阵 + lt.59-螺旋矩阵II + lt.74-搜索二维矩阵 + 剑指Offer.29-顺时针打印矩阵 (待补充完善)
[思路分析]

  • 数组和矩阵一起结合考察(用数组模拟矩阵), 偏数学思想, 机器学习领域考察那是相当的多, 管咱屁事哈哈, 既然遇到了, 就把考察频度高的几道题甩出来
  1. 螺旋矩阵,即顺时针读取矩阵, 记录到结果集合中并返回,
  2. 我们最常用的解法就是, 记录矩阵的四个角, 不断的缩小角之间的范围, 直到目标数组中只剩下单纯的一列或一行数据, 甚至就剩一个数字, 同时也要记得把每次遍历的两个角之间的数, 添加到用于返回的集合中;
  3. 看上图最下面的提示, 矩阵是不为空的, 所以数组不会为空, 我们也不需要加什么特例条件了;
  4. 我们用left和right, 来记录每次左右遍历矩阵的左角和右角, 所以很显然, 从左向右遍历就是从left–>right遍历数组, 从右向左遍历就是从right–>left遍历数组;
  5. 我们用top和bottom,来记录每次上下遍历矩阵的上角和下角, 所以也很显然, 从上到下遍历就是从top–>bottom遍历数组, 从下到上遍历就是从bottom–>top遍历数组;
  6. 旋转跳跃我闭眼, 当我们左->右, 上->下, 右->左, 下->上遍历到矩阵只剩下一行或者一列,或者一个数字的时候, 再来一次顺序循环, 添加进集合, 就大功告成了 4. tag数组和矩阵-lt.54-螺旋矩阵 + lt.59-螺旋矩阵II + lt.74-搜索二维矩阵 + 剑指Offer.29-顺时针打印矩阵 (待补充完善)
  • 参考文章:

[代码实现]

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        //定义四个角
        // top --> bottom 是从上往下遍历
        // left --> right 是从左往右遍历
        int top = 0;    //top指明哪一行的行首
        int bottom = matrix.length - 1; //bottom 指明哪一行的数目
        int left = 0;   //left指明哪一列的列首
        int right = matrix[0].length - 1; //right指明哪一列

        //特例(无,)因为题目给了:     1 <= matrix.length <= 10
        //
        //结果集合
        List<Integer> list = new ArrayList<>();

        while(top < bottom && left < right){
            //从左到右遍历, 放入list
            for(int i = left; i < right; i++){list.add(matrix[top][i]);} //当前top行的每一列
            for(int i = top; i < bottom; i++){list.add(matrix[i][right]);} //当前right列的每一行
            for(int i = right; i > left; i--){list.add(matrix[bottom][i]);} //当前bottom行的每一列
            for(int i = bottom; i > top; i--){list.add(matrix[i][left]);} //当前left列的每一行

            ++left;
            --right;
            ++top;
            --bottom;
        }

        //边缘判断(当只剩下了一行. 或者一列, 或者一个数, 直接一次遍历加入集合即可)
        //只剩下顺序一行
        if(bottom == top){
            for(int i = left; i <=right; i++){list.add(matrix[top][i]);}
        }else if (left == right){
            for(int i = top; i <= bottom; i++){list.add(matrix[i][top]);}
        }
        return list;   
    }
}

lt.59-螺旋矩阵 II

[案例需求]

[思路分析]
[代码实现]

lt.74-搜索二维矩阵

[案例需求]

[思路分析]
[代码实现]

class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
        //解法一, 遍历
        //从矩阵的右端开始遍历:
        //1. 遍历数 < 当前数, 跳到下一行进行遍历;
        //2. 遍历数 > 当前述, 本行内往前进行遍历(倒序遍历)
        //3. 遍历数 == 当前数, 直接return true;

        //外层循环控制二维数组中的每个一维数组, 内层循环控制一维数组中的每个数
        for(int i = 0; i < matrix.length; i++){
            //二维数组中的每个数组的最后一个数的下标;
            int last = matrix[i].length - 1;
           
            for(int j = last; j >=0; j--){
                if(target == matrix[i][j]) return true;

                if(target > matrix[i][j]) continue;
            }
        }
        return false;
    }
}

剑指Offer.29-顺时针打印矩阵

[案例需求]
4. tag数组和矩阵-lt.54-螺旋矩阵 + lt.59-螺旋矩阵II + lt.74-搜索二维矩阵 + 剑指Offer.29-顺时针打印矩阵 (待补充完善)

[思路分析]

  • 解题思路跟 lt54. 螺旋矩阵完全相同, 只不过最后返回的是一个int类型的数组, 如果我们前面用的是list存储的话, 还需要把list数组转换为int类型的数组;
  • 在这里要特别注意: List<Integer> 是不能直接转换为 int[] 数组的, 使用 list.toAarry(int[]) 也不行! —> 补充文章
    [代码实现]
class Solution {
    public int[] spiralOrder(int[][] matrix) {

        //特例
        if(matrix.length == 0 || matrix[0].length == 0) return new int[]{};
        //记录四个角, 由左向右打印, 由上到下打印, 由右向做打印, 由下向上打印;
        // left和right控制列, top和bottom控制行
        int left = 0;
        int right = matrix[0].length - 1;
        int top = 0;
        int bottom = matrix.length - 1;

        //集合, 到最后会返回数组(集合->数组)
        List<Integer> list = new ArrayList<>();

        while(left < right && top < bottom){
            for(int i  = left; i < right; i++){list.add(matrix[top][i]);}
            for(int i = top; i < bottom; i++){list.add(matrix[i][right]);}
            for(int i = right; i > left; i--){list.add(matrix[bottom][i]);}
            for(int i = bottom; i > top; i--){list.add(matrix[i][left]);}

            ++left;
            --right;
            ++top;
            --bottom;
        }

        //仅剩下一行了
        if(bottom == top){
            for(int i = left; i <= right; i++){
                list.add(matrix[top][i]);
            }//仅剩下一列了
        }else if(left == right){
            for(int i = top; i <=bottom; i++){
                list.add(matrix[i][left]);
            }
        }
         int[] arr = list.stream().mapToInt(Integer::valueOf).toArray();
    
        return arr;
    }
}
上一篇:安卓可移动悬浮按钮


下一篇:刷题日记(6. Z 字形变换)