二维数组经典问题

解决二维数组问题需要注意的几个点:

  • 二维数组中行数和列数不一定相同,注意具体情况
  • 多通过画图等手段找到索引之间的规律
  • 注意数组的边界条件

旋转矩阵

旋转90度实际上是四个数字交换位置,那么我们只要遍历四分之一的数组,每次找到另外三个点,交换它们的位置就可以了。

如何交换呢,我们假设4个数字按顺时针顺序分别为1,2,3,4,则交换以后原来位置上应该是4,1,2,3.

而需要遍历的那四分之一数组就是正方形的上边为底的等腰直角三角形,如下图,注意三角的右对角线上的数字是不用遍历的,因为它们与左对角线重复了。

public class Solution {
    public void Rotate(int[][] matrix) {
        int size=matrix.Length;
        int i,j;
        for(i=0;i<size/2;i++)
        for(j=i;j<size-i-1;j++)
        r(matrix,i,j,size);

    }
    public void r(int[][] matrix,int i,int j,int size)
    {
        int a,b,c,d;
        a=matrix[i][j];
        b=matrix[j][size-1-i];
        c=matrix[size-1-i][size-1-j];
        d=matrix[size-1-j][i];
        matrix[i][j]=d;
        matrix[j][size-1-i]=a;
        matrix[size-1-i][size-1-j]=b;
        matrix[size-1-j][i]=c;
    }
}

 零矩阵

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

注意这题中矩阵的行数和列数可能是不同的。

我们先遍历矩阵,用一个数组记下所有为零的索引,再根据索引矩阵将同行和列的都变为零。

public class Solution {
    public void SetZeroes(int[][] matrix) {
        int sizex=matrix.Length;
        int sizey=matrix[0].Length;
        int[,] index=new int[sizex*sizey,2];
        int i,j,k=0;
        for(i=0;i<sizex;i++)
        for(j=0;j<sizey;j++)
        {
            if(matrix[i][j]==0)
            {
                index[k,0]=i;
                index[k,1]=j;
                k++;
            }
        }
        if(k!=0)
        for(i=0;i<k;i++)
        {
            int x=index[i,0];
            int y=index[i,1];
            for(j=0;j<sizey;j++)
            matrix[x][j]=0;
            for(j=0;j<sizex;j++)
            matrix[j][y]=0;
        }
    }
}

 对角线遍历

 这题首先要明确几个点:

  • 对角线的条数=m+n-1
  • 每条对角线上的索引之和相同
  • 第i条对角线的方向是根据i的奇偶性决定的
  • 当对角超过矩阵的对角线时,它的开始和结束条件是比较复杂的

针对第四点,我们不妨把矩形的左边和上边延长,使得对角线可以从行标或列表为开始,然后再把不符合边界条件的剔除。如下图所示

 

public class Solution {
    public int[] FindDiagonalOrder(int[][] mat) {
        int m=mat.Length;
        int n=mat[0].Length;
        int i,j,k=0;
        int[] a=new int[m*n];
        for(i=0;i<m+n-1;i++)
        {
            for(j=0;j<=i;j++)
            {
                if(i%2==1&&j<m&&i-j<n)
                {a[k]=mat[j][i-j];k++;}
                if(i%2==0&&i-j<m&&j<n)
                {a[k]=mat[i-j][j];k++;}
            }
        }
        return a;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值