アルゴリズム-マトリックストラバーサル問題アルバム

1.スパイラルマトリックス

54.スパイラルマトリックス

给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

示例 1:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:

输入:
[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]

この問題は実際には非常に単純です。解決策の鍵は、トラバーサルの境界条件をどのように決定するかです。

マトリックスをタマネギと見なして、マトリックスの中心を層ごとに突き刺します。つまり、マトリックスのレイヤーです。
2つの変数を定義します。現在のレイヤー、残りの印刷されていない要素の数が境界条件としてカウントされます

次に、左から右、東から下、右から左、下から上の4方向をトラバースして、レイヤー番号の条件を完成させます。印刷するたびに、1つの要素を減算します。要素がに縮小されると、 0、トラバーサルを終了します

    public List<Integer> spiralOrder(int[][] matrix) {
    
    
        List<Integer> list=new ArrayList<>();
        if(matrix.length==0){
    
    
            return list;
        }
        int m=matrix.length-1;
        int n=matrix[0].length-1;
        int count=(m+1)*(n+1);
        int layer=0;
        while (count>0){
    
    
            //从左到右
            for (int i=layer;i<=n-layer&&count>0;i++){
    
    
                list.add(matrix[layer][i]);
                count--;
            }
            //从上到下
            for (int i=layer+1;i<=m-layer&&count>0;i++){
    
    
                list.add(matrix[i][n-layer]);
                count--;
            }
            //从右到左
            for (int i=n-layer-1;i>=layer&&count>0;i--){
    
    
                list.add(matrix[m-layer][i]);
                count--;
            }
            //从下到上
            for (int i=m-layer-1;i>layer&&count>0;i--){
    
    
                list.add(matrix[i][layer]);
                count--;
            }
            layer++;//读完一层,继续下一层
        }
        return list;
    }

2.画像​​を回転させます

最初にタイトルの説明を見てください。

48.画像を回転させる

给定一个 n × n 的二维矩阵表示一个图像。

将图像顺时针旋转 90 度。

说明:

你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]
示例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

この質問は数学の質問に似ていると思います。この質問には2つの解決策があります。

最初のタイプ:要素を時計回りに配列に読み込み、配列要素を調整して
2番目のタイプを埋めます:マトリックスを転置してから、行ごとに反転します

最初の書き方はもっと面倒です、これが2番目の書き方です

    public void rotate(int[][] matrix) {
    
    
        int n=matrix.length;
        //矩阵转置
        for(int i=0;i<n;i++){
    
    
            for(int j=0;j<=i;j++){
    
    
                int temp=matrix[i][j];
                matrix[i][j]=matrix[j][i];
                matrix[j][i]=temp;
            }
        }
        //按行反转
        for(int i=0;i<n;i++){
    
    
            int left=0,right=n-1;
            while(left<right){
    
    
                int temp=matrix[i][left];
                matrix[i][left]=matrix[i][right];
                matrix[i][right]=temp;
                left++;
                right--;
            }
        }
    }

3.2次元マトリックスIIを検索します

240. 2D MatrixIIを検索する

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:

每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
示例:

现有矩阵 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。

给定 target = 20,返回 false。

この問題の解決策は少し賢い、本質的には剪定方法です。右上隅から検索を開始し、右上隅の値をターゲット値と比較し、一度に1行または列を切り取ります。複雑さは、O(m + n)です。

    public boolean searchMatrix(int[][] matrix, int target) {
    
    
        if(matrix.length==0){
    
    
            return false;
        }
        int right=matrix[0].length-1,top=0;//右上角
        while(right>=0&&top<matrix.length){
    
    
            if(matrix[top][right]>target){
    
    
                right--;//裁掉一列
            }else if(matrix[top][right]<target){
    
    
                top++;//裁掉一行
            }else{
    
    
                return true;
            }
        }
        return false;
    }

4.2次元マトリックスを検索します

74.2Dマトリックスを検索する

编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

每行中的整数从左到右按升序排列。
每行的第一个整数大于前一行的最后一个整数。
示例 1:

输入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 3
输出: true
示例 2:

输入:
matrix = [
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
target = 13
输出: false

これらの2つの質問は同じですが、直接適用してください

    public boolean searchMatrix(int[][] matrix, int target) {
    
    
        if(matrix.length==0){
    
    
            return false;
        }
        int right=matrix[0].length-1,top=0;//右上角
        while(right>=0&&top<matrix.length){
    
    
            if(matrix[top][right]>target){
    
    
                right--;//裁掉一列
            }else if(matrix[top][right]<target){
    
    
                top++;//裁掉一行
            }else{
    
    
                return true;
            }
        }
        return false;
    }

効率は悪くない

执行结果:
通过
显示详情
执行用时 :
0 ms
, 在所有 Java 提交中击败了
100.00%
的用户
内存消耗 :
39.3 MB
, 在所有 Java 提交中击败了
94.29%
的用户

おすすめ

転載: blog.csdn.net/qq_23594799/article/details/105621709