java对角线遍历_Leetcode 498:对角线遍历Diagonal Traverse(python3、java)

对角线遍历

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。 Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image. 示例:

输入:

[

[ 1, 2, 3 ],

[ 4, 5, 6 ],

[ 7, 8, 9 ]

]

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

解释:

56ae2bc7a966892a6d81dee6607e27ff.png

说明:

给定矩阵中的元素总数不会超过 100000 。

思路:

​ 实例输入的二维数组范围均是0~2

​ 先观察一下遍历规律:(0,0)->(0,1)->(1,0)->(2,0)->(1,1)->(0,2)->(1,2)->(2,1)->(2,2)

​ 数组索引(m,n),两种改变方式1、(m-1,n+1) 2、(m+1,n-1)

​ 数组从(0,0)开始,先是(m-1,n+1) ,(0,0)->(-1,1)此时m=-1,超出范围,m赋值0。然后切换索引改变方式(m+1,n-1),执行两次(0,1)->(1,0)->(2,-1),n赋值0得到(2,0),再次切换为索引改变方式(m-1,n+1)直到下次超出范围(2,0)->(1,1)->(0,2)->(-1,3)。此时m<0且n>2均超出范围,(m+2,n-1),应当优先判断n是否超出范围,执行(m+2,n-1)->(1,2),避免因为m<0再次切换一次索引改变方式。然后正常切换后:(1,2)->(2,1)->(3,0),因为m>2,切换方式并(m-1,n+2)

java:

class Solution {

public int[] findDiagonalOrder(int[][] matrix) {

if (matrix.length==0||matrix[0].length==0)return new int[0];

int col=matrix.length,row=matrix[0].length;

int nums=col*row,m=0,n=0;

int res[]=new int[nums];

boolean flag=true;

for(int i=0;i

res[i]=matrix[m][n];

if(flag){

n+=1; m-=1;

}else{

n-=1; m+=1;

}

if(m>=col){

m-=1; n+=2; flag=true;

}else if(n>=row){

n-=1; m+=2; flag=false;

}

if(m<0){

m=0; flag=false;

}else if(n<0){

n=0; flag=true;

}

}

return res;

}

}

注意点:

​ if (matrix.length==0||matrix[0].length==0)return new int[0];首先判断是否为空数组,另外 matrix.length==0||matrix[0].length==0 判断条件顺序不能颠倒,因为如果 matrix.length==0 后面的 matrix[0].length==0 不会再判断,即返回空数组;但是matrix[0].length==0 在前时,如果输入数组为空,matrix[0] 会报错因为matrix并没有0号索引。

​ for循环里应当先判断m、n是否大于或等于各自的最大长度,然后执行(m-1,n+2)、(m+2,n-1)。避免出现m、n同时小于0时flag布尔值转换两次的错误。

python:

class Solution:

def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]:

if(len(matrix)==0 or len(matrix[0])==0):

return []

col=len(matrix)

row=len(matrix[0])

nums=col*row

m=n=0

flag=True

res=[]

for i in range(nums):

res.append(matrix[m][n])

if flag:

m-=1

n+=1

else:

m+=1

n-=1

if m>=col:

m-=1

n+=2

flag=True

elif n>=row:

m+=2

n-=1

flag=False

if m<0:

m=0

flag=False

elif n<0:

n=0

flag=True

return res

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思想是利用已知信息来避免不必要的字符比较。具体来说,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思想。假设文本串为S="ababababca",模式串为P="abababca",我们想要在S中查找P的出现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P出现在S的第二个位置。 下面是KMP算法的C++代码实现:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值