Matrix class questions (test your code control ability)

content

A helical matrix I

2. Spiral matrix II

3. Rotate the image

Four Diagonal Traversal

5. Matrix zeroing

6. The kth smallest number in an ordered matrix


A helical matrix I

54. Spiral Matrix - LeetCode (leetcode-cn.com)

Topic description:

 Problem solving ideas:

 This question is the same as peeling an onion in our daily life. We first peel the skin and then peel the inside. This problem is also similar. We define a start point and an end point to traverse all its boundaries. Then go inside. Please see the code for details:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
      vector<int>ans;  //记录答案                                              
        int row1=0;//边界开始位置的行
        int col1=0;//边界结束开始位置的列
        int row2=matrix.size()-1;//边界结束的列
        int col2=matrix[0].size()-1;//边界结束的列
        while(row1<=row2&&col1<=col2)//如果两个点错过了说明已经遍历结束了
        {
            Print(matrix,ans,row1++,col1++,row2--,col2--);
        }
            
         return ans;
    }
    void Print(vector<vector<int>>&matrix,vector<int>&ans,int row1,int col1,int row2,int col2)
    {
        if(row1==row2)//两个点的行变成一样了直接从这一行遍将其放入答案中
        {
           for(int i=col1;i<=col2;i++)
           {
               ans.push_back(matrix[row1][i]);
           }
           return;
        }
         //列相等
         if(col1==col2)
         {//直接将这一列遍历放入答案中
            for(int i=row1;i<=row2;i++)
            {
                ans.push_back(matrix[i][col1]);
            }
            return;
         }
        //说明行和列不相等将边框打印
        //提前记录一下方便后序遍历
         int rowStart=row1;
         int colStart=col1;
        while(colStart<col2)//打印最上层的边框
        {
            ans.push_back(matrix[row1][colStart++]);
        }
        //打印往下走的边框
        while(rowStart<row2)
        {
            ans.push_back(matrix[rowStart++][col2]);
        }
        //打印往左走的
        while(colStart>col1)
        {
            ans.push_back(matrix[row2][colStart--]);
        }
        //往上走
        while(rowStart>row1)//注意这里是大于防止重复遍历
        {
            ans.push_back(matrix[rowStart][col1]);
          
            rowStart--;
        }


    }
};

2. Spiral matrix II

59. Spiral Matrix II - LeetCode (leetcode-cn.com)

Topic description:

Problem-solving ideas: After meeting the previous question, you can directly kill this question. You only need to open the space in advance and put the value into the array, which is basically the same as the previous question. Please see the code for details

class Solution {
public:
     int num=1;
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>>ans(n,vector<int>(n));
        int row1=0;
        int col1=0;
        int row2=n-1;
        int col2=n-1;
        while(row1<=row2&&col1<=col2)
        {
            Print(ans,row1++,col1++,row2--,col2--);
        }
        return ans;
    }
     void Print(vector<vector<int>>&ans,int row1,int col1,int row2,int col2)
    {
        if(row1==row2)//两个点的行变成一样了直接从这一行遍将其放入答案中
        {
           for(int i=col1;i<=col2;i++)
           {
               ans[row1][i]=num++;
           }
           return;
        }
         //列相等
         if(col1==col2)
         {//直接将这一列遍历放入答案中
            for(int i=row1;i<=row2;i++)
            {
                ans[i][col1]=num++;
            }
            return;
         }
        //说明行和列不相等将边框打印
        //提前记录一下方便后序遍历
         int rowStart=row1;
         int colStart=col1;
        while(colStart<col2)//打印最上层的边框
        {
            ans[row1][colStart++]=num++;
        }
        //打印往下走的边框
        while(rowStart<row2)
        {
            ans[rowStart++][col2]=num++;
        }
        //打印往左走的
        while(colStart>col1)
        {
            ans[row2][colStart--]=num++;
        }
        //往上走
        while(rowStart>row1)//注意这里是大于防止重复遍历
        {
            ans[rowStart][col1]=num++;
          
            rowStart--;
        }


    }
    
};

3. Rotate the image

Interview Question 01.07. Rotation Matrix - LeetCode (leetcode-cn.com)

Topic description:

 Problem solving ideas:

The realization idea of ​​this question is almost the same as the previous question. First, the outer rotation is done, and then the inner rotation is rotated until the row and the row are equal.

 

As shown in the figure above, since the 11th step D \rightarrow AD→A has overwritten AA (resulting in the loss of AA), this loss causes the final 44th step A \rightarrow BA→B to be unable to assign a value. To solve this problem, consider storing AA in advance with an "auxiliary variable tmptmp", and the rotation operation at this time becomes:

暂存 \ tmp = A \\ A \leftarrow D \leftarrow C \leftarrow B \leftarrow tmp
暂存 tmp=A
A←D←C←B←tmp

 Corresponding code:

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
            int row1=0;
            int col1=0;
            int row2=matrix.size()-1;
            int col2=matrix[0].size()-1;
            while(row1<row2)//如果他们相等了说明不用旋转了
            {
                Rotate(matrix,row1++,col1++,row2--,col2--);
            }
            

    }
    void Rotate(vector<vector<int>>&matrix,int row1,int col1,int row2,int col2)
    {
            for(int i=0;i<col2-col1;i++)
            {
            int tmp=matrix[row1][col1+i];//旋转的第一个元素
             matrix[row1][col1+i] =matrix[row2-i][col1];//这一组最后一个元素覆盖第一个位置
             matrix[row2-i][col1]=matrix[row2][col2-i];//依次覆盖
             matrix[row2][col2-i]=matrix[row1+i][col2];
             matrix[row1+i][col2]=tmp;//将第一个元素放到正确的位置
            }
            
    }
};

Four Diagonal Traversal

498. Diagonal Traversal - LeetCode (leetcode-cn.com)

Topic description:

Problem solving ideas:

A positive diagonal has a property: the sum of the (x, y) coordinates of each point on the same diagonal is equal. By observing the easy-to-know matrix, there are a total of m + n - 1 diagonal lines, each diagonal line is either from the lower left to the upper right, or from the upper right to the lower left, first find these two endpoints, and then traverse according to the direction of the current loop .
According to the nature of the diagonal, as long as one of the abscissa and ordinate coordinates of the endpoint is known, another dimension can be obtained. In the legend, we only care about the abscissa.

Corresponding code:

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
             int endRow=mat.size()-1;
             int endCol=mat[0].size()-1;
             int row1=0;
             int col1=0;
             int row2=0;
             int col2=0;
             vector<int>ans;
             bool fromUp=false;
             while(row1<=endRow)
             {
                 Print(mat,ans,row1,col1,row2,col2,fromUp);
                 row1=col1==endCol?row1+1:row1;//

                 col1=col1==endCol?col1:col1+1;

                  col2=row2==endRow?col2+1:col2;
                  //注意这里要先判断否则会错过最后一些数据老铁可以思考一下

                 row2=row2==endRow?row2:row2+1;
                
                 fromUp=!fromUp;//方向每次取反
             }
             return ans;
    }
    void Print(vector<vector<int>>&mat,vector<int>&ans,int row1,int col1,int row2,int col2,bool fromUp)
    {
           if(fromUp)//如果为true说明是从上面往下面遍历
           {
               while(row1<=row2)
               {
                   ans.push_back(mat[row1++][col1--]);
               }

           }
           else//说明是从下面往上面遍历
           {
                 while(row2>=row1)
                 {
                     ans.push_back(mat[row2--][col2++]);
                 }
           }
    }
};

5. Matrix zeroing

Interview Question 01.08. Zero Matrix - LeetCode (leetcode-cn.com)

Topic description:

 Problem solving ideas:

1. Use the 0th column and the 0th row to mark whether a certain row and a certain column should be set to 0. After the traversal is completed, traverse the 0th row and the 0th column to determine whether a certain position should be set to 0, but the problem comes If there is 0 in the 0th row and 0th column, so we need to record it with a variable and handle it separately. Please see the code for details.

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
           bool iscol=false;//标记第一行是否要置0
           bool isrow=false;//标记第一列是否要置0;
           for(int i=0;i<matrix[0].size();i++)
           {
               //遍历第一行是否要置0
               if(matrix[0][i]==0)
                 isrow=true;
           }
           for(int i=0;i<matrix.size();i++)
           {
               if(matrix[i][0]==0)
               {
                   iscol=true;
               }
           }
           //用0行和第0列的元素标记这一行和这一列是否需要置0
           for(int i=1;i<matrix.size();i++)
           {
               for(int j=1;j<matrix[0].size();j++)
               {
                   if(matrix[i][j]==0)
                   {
                       matrix[0][j]=0;
                       matrix[i][0]=0;
                   }
               }
           }
           //在遍历一次完成置0
           for(int i=1;i<matrix.size();i++)
           {
               for(int j=1;j<matrix[0].size();j++)
               {
                   if(matrix[0][j]==0||matrix[i][0]==0)
                   //对应第0行的位置和第一列的位置
                   //只要有一个为0就说明这个位置需要被置为0;
                   {
                       matrix[i][j]=0;
                   }
               }
           }
        //单独判断第一行和第一列是否需要置0
        if(isrow)//说明第0行需要置0
        {
           for(int i=0;i<matrix[0].size();i++)
           {
               matrix[0][i]=0;
           }
        }
        if(iscol)//说明第一列需要置0
        {
          for(int i=0;i<matrix.size();i++)
           {
                matrix[i][0]=0;
           }
        }
        //处理结束
    }

};

6. The kth smallest number in an ordered matrix

378. The K-th Smallest Element in an Ordered Matrix - LeetCode (leetcode-cn.com)

Topic description:

Problem solving ideas:

 

The idea is very simple:

1. Find the smallest number left and the largest number right in the two-dimensional matrix, then the k-th smallest number must be between left ~ right mid=(left+right)/2; find less than or equal to mid in the two-dimensional matrix 2. If this count
is less than k, it means that the kth smallest number is in the right half and does not contain mid, that is, leftd=mid+1, right=right, which ensures that the kth smallest number is in the left Between ~ right
3. If this count is greater than k, it means that the kth smallest number is in the left half and may contain mid, that is, left=left, right=mid, which ensures that the kth smallest number is between left and right
4. Because the kth smallest number is guaranteed to be between left and right in each loop, when left==right, the kth smallest number is found, which is equal to right

Corresponding code:

class Solution {
public:
       struct Info
       {
           Info(int n,int cnt)
           {
               near=n;
              num=cnt;
           }
           int near;
           int num;
       };
    int kthSmallest(vector<vector<int>>& matrix, int k) {
        int n=matrix.size();
         int left=matrix[0][0];
         int right=matrix[n-1][n-1];
         int ans=0;
        while(left<=right)
        {
            int mid=(left+right)/2;//取中点二分
            Info* ret=getLessEqualNum(matrix,mid);//看一下小于等于mid的有多少个
            if(ret->num<k)//如果小于k说明二分的中点小了
            {
                left=mid+1;
            }
            else{//大于等于更新ans;
                right=mid-1;
                ans=ret->near;
            }
        }
        return ans;//返回ans
    }
    Info*getLessEqualNum(vector<vector<int>>&matrix,int val)
    {
        int m=0;
        int n=matrix[0].size()-1;
        int num=0;
        int near=INT_MIN;//记录小于等于val离val最近的数
        while(m<matrix.size()&&n>=0)
        {
            if(matrix[m][n]<=val)
            {
              num+=n+1;//把小于val的个数加起来
              near=max(near,matrix[m][n]);//更新near
              m++;
            }
            else
            {
                n--;
            }
        }
        return new Info(near,num);//返回结果
    }
};

Guess you like

Origin blog.csdn.net/qq_56999918/article/details/123790380