Java 这个代码是不是代表;旋转矩阵;聪明还是天真?O(1)方法
我只是在一些随机情况下遇到了矩阵旋转。最明显的方法是将元素从(nxm)矩阵A映射到“A”,其中A是具有(mxn)的新矩阵。这里是一些伪代码,O(nm),用于这个明显的方法Java 这个代码是不是代表;旋转矩阵;聪明还是天真?O(1)方法,java,algorithm,Java,Algorithm,我只是在一些随机情况下遇到了矩阵旋转。最明显的方法是将元素从(nxm)矩阵A映射到“A”,其中A是具有(mxn)的新矩阵。这里是一些伪代码,O(nm),用于这个明显的方法 def rotateRight(A[1..n][1..m]): // O(nm) let A'[1..m][1..n] be a new matrix for i from 1 to n: for j from 1 to m: A'[n-j][i] = A[i][j] /
def rotateRight(A[1..n][1..m]): // O(nm)
let A'[1..m][1..n] be a new matrix
for i from 1 to n:
for j from 1 to m:
A'[n-j][i] = A[i][j] // not sure if this is right
return A'
上面的代码看起来很典型。然而,经过一些思考,我实际上认为我们可以做得更好
无论如何旋转,矩阵只能有4个方向(北、东、南、西)。下面是一个例子:
通过封装矩阵的内部表示并为元素提供getter方法,我们实际上可以实现如下所示的rotate
class Matrix{
private (final) elements[n][m];
private getElemStrategies = [getElemNorth, getElemEast, getElemSouth, getElemWest];
private currentStrategy = 0;
public getElem(x, y){
return getElemStrategies[currentStrategy];
}
public rotateRight(){ // O(1)
currentStrategy = (currentStrategy + 1) % 4
}
}
这里的getElemNorth
,getElemEast
,getElemSouth
,getElemWest
只是getter方法对应于矩阵的当前方向。具体来说,getElemEast
类似于:
def getElemEast(x, y)
return this.elements[n-j][i]
该方法采用实际有效的O(1)。我认为它很酷,但不确定它的正确性。这种方法有名字吗?这是一种非常标准的技术 例如,为了更好地解释,我建议大家阅读NumPy步幅是如何工作的
要记住的一点是,引用的位置很重要:扫描内存中的连续位置要比读取分散在各地的相同数量的数据便宜得多。取决于你对矩阵所做的操作,这可能会抵消通过恒定时间旋转所获得的节省。你能解释O(1)到底是什么吗?哪种算法或操作?这里你解释了如何得到一个“旋转”矩阵的元素,但是你还没有旋转它,是吗?注意:我没有检查正确性。特别是rotateRight()方法。据我所知,它只是设置了策略,但还没有旋转。这基本上只是懒惰的评估。你将成本推迟到以后,如果你只做很少的查找,这会更便宜。这是一种相当标准的技术,但我不确定它是否有一个标准名称(我想不出一个)。例如,
numpy.fliplr
()和转置。