二维阵列圆旋转算法?

时间:2016-05-19 16:48:41

标签: algorithm

给出NxN二维数组。编写一个顺时针旋转1个元素的函数(几乎绕圈移动)。

[1][2][3][4]
[5][6][7][8]
[9][0][1][2]
[3][4][5][6]

变为:

[5][1][2][3]
[9][0][6][4]
[3][1][7][8]
[4][5][6][2]

更新: 这是一个在线访谈问题 - HackerRank。我无法解决它。到目前为止我在StackOverflow中找到的都是90度旋转(如果你在某个地方找到这个问题,请在评论中分享链接)。

3 个答案:

答案 0 :(得分:1)

我不太确定你遇到了什么样的问题,因为明显的解决方案效果很好:

原始数组:

final int[][] a = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 0, 1, 2}, {3, 4, 5, 6}};

度:

for (int i = 0; i < (a.length >>> 1); i++) {
    final int minx = i;
    final int miny = i;
    final int maxx = a.length - 1 - i;
    final int maxy = a.length - 1 - i;

    int incx = 1, incy = 0;
    int prev = a[miny][minx];
    for (int x = (minx + 1), y = miny; ((x != minx) || (y != miny)); x += incx, y += incy) {
        final int temp = a[y][x];
        a[y][x] = prev;
        prev = temp;
        if ((x == maxx) && (incx == 1)) {
            incx = 0;
            incy = 1;
        }
        if ((y == maxy) && (incy == 1)) {
            incx = -1;
            incy = 0;
        }
        if ((x == minx) && (incx == -1)) {
            incx = 0;
            incy = -1;
        }
    }
    a[miny][minx] = prev;
}

输出:

5 1 2 3 
9 0 6 4 
3 1 7 8 
4 5 6 2 

答案 1 :(得分:0)

Java中的另一个解决方案。

声明行和列距离而不是计算。

final int[][] a = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 0, 1, 2 },
                { 3, 4, 5, 6 } };

final int[][] dRow = { { 1, 0, 0, 0 }, { 1, 1, 0, -1 },
                { 1, 0, -1, -1 }, { 0, 0, 0, -1 } };
final int[][] dCol = { { 0, -1, -1, -1 }, { 0, 0, -1, 0 },
                { 0, 1, 0, 0 }, { 1, 1, 1, 0 } };

int[][] tmp = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
                { 0, 0, 0, 0 } };

// rotate a to tmp
for (int row = 0; row < a.length; row++)
    for (int col = 0; col < a[row].length; col++)
        tmp[row][col] = a[row + dRow[row][col]][col + dCol[row][col]];

// copy tmp to a
for (int row = 0; row < a.length; row++)
    for (int col = 0; col < a[row].length; col++)
        a[row][col] = tmp[row][col];

// show result
for (int row = 0; row < a.length; row++)
    for (int col = 0; col < a[row].length; col++)
        System.out.print((col == 0 ? "\n" : "") + a[row][col]);

答案 2 :(得分:0)

我很快就给了这个,用Python稍微不同的方法矩阵(你指定NxN)。对于每一层,我打开,旋转并重新应用。这肯定工作超过必要的工作,但很容易追踪和感觉合乎逻辑 - 并且适用于+ -n步旋转。

 Node2

    import rospy
    import time
    from std_msgs.msg import Float64
    global x2 
    global a 
    x2 = 2.4
    def callback(msg):
        #print 'Sto ricevendo informazioni da %s nel tempo %s' % (msg.data, time.ctime())
         #print "%f"%msg.data     
        a = msg.data  
        info_nodo1 = a + 0.5
        x2 = info_nodo1
        print "%f"%x2
    def nodo():
        pub = rospy.Publisher('chatter2', Float64)
        rospy.init_node('nodo2', anonymous=True)
        rospy.loginfo("In attesa")
        rospy.Subscriber('chatter1', Float64, callback) 
        rate = rospy.Rate(1) # 10hz   
        while not rospy.is_shutdown():
            for i in range(1,51):
               # num = "%s" % (x2)
                #rospy.loginfo(num)
                pub.publish(x2)
                rate.sleep()
            rospy.spin() 
    if __name__ == '__main__':
        try:
            nodo()
        except rospy.ROSInterruptException:
            pass