आप दो आयामी सरणी कैसे घुमाते हैं?


302

रेमंड चेन के पद से प्रेरित , कहते हैं कि आपके पास 4x4 दो आयामी सरणी है, एक फ़ंक्शन लिखें जो इसे 90 डिग्री घुमाता है। रेमंड छद्म कोड में एक समाधान के लिए लिंक करता है, लेकिन मैं कुछ वास्तविक दुनिया सामान देखना चाहता हूं।

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

हो जाता है:

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

अपडेट : निक का जवाब सबसे सीधा है, लेकिन क्या इसे n ^ 2 से बेहतर करने का कोई तरीका है? यदि मैट्रिक्स 10000x10000 था तो क्या होगा?


99
आप संभवतः n ^ 2 से कम के साथ कैसे दूर हो सकते हैं? सभी तत्वों को पढ़ना और सेट करना होगा, और n ^ 2 तत्व हैं
erikkallen


9
आपका एन क्या है? आप यह नहीं कहते हैं कि 2 डी सरणी वर्गाकार है (यह सामान्य स्थिति में नहीं है! जैसे कि एक वेक्टर 1 के एक आयाम वाला एक मैट्रिक्स है), फिर भी आपको लगता है कि n की चौड़ाई और ऊंचाई है, और इसलिए n 2D तत्व हैं । यह अधिक समझ में आता है n n तत्वों की संख्या होगी, n = w × h के साथ।
नीकर

1
यहां यह करने का एक तेज़ तरीका है: पंक्ति और स्तंभ सूचकांकों को संग्रहीत करें (I और j कहते हैं)। पारगमन को निरंतर समय लगता है (सिर्फ सूचकांकों को स्वैप करें :)। आप घुमाव (सूचक के साथ खेलना) के साथ भी ऐसा कर सकते हैं।
साढ़ेसाती

4
मामले में n ^ 2 संभव नहीं है। आप एक इंटरफ़ेस बना सकते हैं जो प्रत्येक तत्व को एक्सेस करता है। फिर दिया (i, j), घुमाए गए तत्व तक पहुंच (i, j) के लिए रोटेशन लागू करें और वापस लौटें। हो सकता है कि सबसे अच्छा सोल न हो लेकिन काम करता है।
कंफ्यूज

जवाबों:


140

यहाँ यह C # में है

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

int[,] rotated = RotateMatrix(array, 4);

static int[,] RotateMatrix(int[,] matrix, int n) {
    int[,] ret = new int[n, n];

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            ret[i, j] = matrix[n - j - 1, i];
        }
    }

    return ret;
}

6
ज़रूर, लेकिन O (1) मेमोरी का उपयोग करके समाधान के बारे में क्या?
अलेक्सईएमके

20
आपके समाधान में O (n ^ 2) स्थान की जटिलता है। बेहतर करने की आवश्यकता है
क्षितिज जैन

6
NXM मैट्रिक्स के लिए कैसे?
रोहित

17
सरणी में तत्वों की संख्या में जटिलता रैखिक है। यदि N तत्वों की संख्या है तो जटिलता O (N) है। यदि N पक्ष की लंबाई है, तो हां, जटिलता O (N ^ 2) है, लेकिन यह अभी भी इष्टतम है। आपको हर तत्व को कम से कम एक बार पढ़ना होगा। मैट्रिक्स प्रिंट करना एक ही जटिलता है
एलेजांद्रो

6
एक -90 डिग्री रोटेशन के लिए: ret[i][j] = matrix[j][n - i - 1]
डंकन लुक

387

O (n ^ 2) समय और O (1) अंतरिक्ष एल्गोरिथ्म (बिना किसी वर्कआराड्स और हेंकी-पैंकी सामान के!)।

+90 से घुमाएँ:

  1. खिसकाना
  2. प्रत्येक पंक्ति को उलट दें

-90 से घुमाएँ:

विधि 1:

  1. खिसकाना
  2. प्रत्येक कॉलम को उल्टा करें

विधि 2:

  1. प्रत्येक पंक्ति को उलट दें
  2. खिसकाना

+180 द्वारा घुमाएँ:

विधि 1 : दो बार +90 से घुमाएँ

विधि 2 : प्रत्येक पंक्ति को उल्टा करें और फिर प्रत्येक स्तंभ को उल्टा करें (स्थानांतरित करें)

-180 से घुमाएँ:

विधि 1 : -90 से दो बार घुमाएँ

विधि 2 : प्रत्येक स्तंभ को उल्टा करें और फिर प्रत्येक पंक्ति को उल्टा करें

विधि 3 : जैसे वे समान हैं, +180 से घुमाएँ


4
यह मेरे लिए बहुत मददगार था; इस ऑपरेशन के "[छद्म-] कोड संस्करण" को जानने के बाद मैं एक एल्गोरिथ्म लिखने में सक्षम था। धन्यवाद!
ड्यूमा

13
मेरे सभी समय के पसंदीदा एसओ में से एक। बहुत शिक्षाप्रद!
g33kz0r

2
अगर किसी को दिलचस्पी है तो यहां जावास्क्रिप्ट कार्यान्वयन JSFiddle है।
श्री पॉलीविरल

6
-90 से घुमाएँ: (1) प्रत्येक पंक्ति को उल्टा करें; (२) पारगमन करना। हास्केल: rotateCW = map reverse . transposeऔरrotateCCW = transpose . map reverse
थॉमस एडिंग

5
180 और -180 घूमने में क्या अंतर है?
कियान चेन

177

मैं थोड़ा और विस्तार जोड़ना चाहूंगा। इस उत्तर में, प्रमुख अवधारणाओं को दोहराया जाता है, गति धीमी और जानबूझकर दोहरावदार होती है। यहां प्रदान किया गया समाधान सबसे अधिक सघन रूप से कॉम्पैक्ट नहीं है, हालांकि, यह उन लोगों के लिए है जो सीखना चाहते हैं कि मैट्रिक्स रोटेशन क्या है और परिणामस्वरूप कार्यान्वयन।

सबसे पहले, एक मैट्रिक्स क्या है? इस उत्तर के प्रयोजनों के लिए, एक मैट्रिक्स सिर्फ एक ग्रिड है जहां चौड़ाई और ऊंचाई समान होती है। ध्यान दें, एक मैट्रिक्स की चौड़ाई और ऊंचाई अलग-अलग हो सकती है, लेकिन सादगी के लिए, यह ट्यूटोरियल केवल समान चौड़ाई और ऊंचाई ( वर्ग मैट्रिसेस ) के साथ मैट्रिसेस को मानता है । और हाँ, मैट्रिक्स मैट्रिक्स का बहुवचन है।

उदाहरण मैट्रीस हैं: 2 × 2, 3 × 3 या 5 × 5। या, अधिक सामान्यतः, एन × एन। 2 × 2 मैट्रिक्स में 4 वर्ग होंगे क्योंकि 2 × 2 = 4। 5 × 5 मैट्रिक्स में 25 वर्ग होंगे क्योंकि 5 × 5 = 25। प्रत्येक वर्ग को एक तत्व या प्रविष्टि कहा जाता है। हम .नीचे दिए गए चित्र में एक अवधि के साथ प्रत्येक तत्व का प्रतिनिधित्व करेंगे :

2 × 2 मैट्रिक्स

. .
. .

3 × 3 मैट्रिक्स

. . .
. . .
. . .

4 × 4 मैट्रिक्स

. . . .
. . . .
. . . .
. . . .

तो, मैट्रिक्स को घुमाने का क्या मतलब है? आइए 2 × 2 मैट्रिक्स लें और प्रत्येक तत्व में कुछ संख्याएं डालें ताकि रोटेशन को देखा जा सके:

0 1
2 3

इसे 90 डिग्री से घुमाकर हमें देता है:

2 0
3 1

हमने कार की स्टीयरिंग व्हील को मोड़ने की तरह ही पूरे मैट्रिक्स को एक बार दाईं ओर मोड़ दिया। यह मैट्रिक्स को उसके दाईं ओर "टिपिंग" के बारे में सोचने में मदद कर सकता है। हम पायथन में एक फ़ंक्शन लिखना चाहते हैं, जो एक मैट्रिक्स लेता है और एक बार दाईं ओर घूमता है। समारोह हस्ताक्षर होंगे:

def rotate(matrix):
    # Algorithm goes here.

मैट्रिक्स को द्वि-आयामी सरणी का उपयोग करके परिभाषित किया जाएगा:

matrix = [
    [0,1],
    [2,3]
]

इसलिए पहली इंडेक्स स्थिति पंक्ति तक पहुंचती है। दूसरी अनुक्रमणिका स्थिति स्तंभ तक पहुँचती है:

matrix[row][column]

हम मैट्रिक्स प्रिंट करने के लिए एक उपयोगिता फ़ंक्शन को परिभाषित करेंगे।

def print_matrix(matrix):
    for row in matrix:
        print row

मैट्रिक्स को घुमाने का एक तरीका यह है कि इसे एक बार में एक परत किया जाए। लेकिन एक परत क्या है? एक प्याज के बारे में सोचो। प्याज की परतों की तरह, प्रत्येक परत को हटाने के बाद, हम केंद्र की ओर बढ़ते हैं। अन्य उपमाएँ ए मैट्रीशोका गुड़िया या पास-द-पार्सल का खेल है।

एक मैट्रिक्स की चौड़ाई और ऊंचाई उस मैट्रिक्स में परतों की संख्या निर्धारित करती है। आइए प्रत्येक परत के लिए अलग-अलग प्रतीकों का उपयोग करें:

2 × 2 मैट्रिक्स में 1 परत होती है

. .
. .

एक 3 × 3 मैट्रिक्स में 2 परतें होती हैं

. . .
. x .
. . .

4 × 4 मैट्रिक्स में 2 परतें होती हैं

. . . .
. x x .
. x x .
. . . .

5 × 5 मैट्रिक्स में 3 परतें होती हैं

. . . . .
. x x x .
. x O x .
. x x x .
. . . . .

एक 6 × 6 मैट्रिक्स में 3 परतें होती हैं

. . . . . .
. x x x x .
. x O O x .
. x O O x .
. x x x x .
. . . . . .

7 × 7 मैट्रिक्स में 4 परतें होती हैं

. . . . . . .
. x x x x x .
. x O O O x .
. x O - O x .
. x O O O x .
. x x x x x .
. . . . . . .

आप देख सकते हैं कि मैट्रिक्स की चौड़ाई और ऊंचाई को एक-एक करके बढ़ाते हुए, हमेशा परतों की संख्या में वृद्धि नहीं होती है। उपरोक्त मैट्रिसेस को लेते हुए और परतों और आयामों को सारणीबद्ध करते हुए, हम देखते हैं कि चौड़ाई की प्रत्येक दो वृद्धि के लिए परतों की संख्या एक बार बढ़ जाती है:

+-----+--------+
| N×N | Layers |
+-----+--------+
| 1×1 |      1 |
| 2×2 |      1 |
| 3×3 |      2 |
| 4×4 |      2 |
| 5×5 |      3 |
| 6×6 |      3 |
| 7×7 |      4 |
+-----+--------+

हालांकि, सभी परतों को घूर्णन की आवश्यकता नहीं है। रोटेशन से पहले और बाद में एक 1 × 1 मैट्रिक्स समान है। केंद्रीय 1 × 1 परत हमेशा रोटेशन से पहले और बाद में एक ही होती है, चाहे समग्र मैट्रिक्स कितना भी बड़ा क्यों न हो:

+-----+--------+------------------+
| N×N | Layers | Rotatable Layers |
+-----+--------+------------------+
| 1×1 |      1 |                0 |
| 2×2 |      1 |                1 |
| 3×3 |      2 |                1 |
| 4×4 |      2 |                2 |
| 5×5 |      3 |                2 |
| 6×6 |      3 |                3 |
| 7×7 |      4 |                3 |
+-----+--------+------------------+

N × N मैट्रिक्स को देखते हुए, हम प्रोग्राम को उन परतों की संख्या कैसे निर्धारित कर सकते हैं जिन्हें हमें घुमाने की आवश्यकता है? यदि हम चौड़ाई या ऊँचाई को दो से विभाजित करते हैं और शेष को अनदेखा करते हैं तो हमें निम्नलिखित परिणाम मिलते हैं।

+-----+--------+------------------+---------+
| N×N | Layers | Rotatable Layers |   N/2   |
+-----+--------+------------------+---------+
| 1×1 |      1 |                0 | 1/2 = 0 |
| 2×2 |      1 |                1 | 2/2 = 1 |
| 3×3 |      2 |                1 | 3/2 = 1 |
| 4×4 |      2 |                2 | 4/2 = 2 |
| 5×5 |      3 |                2 | 5/2 = 2 |
| 6×6 |      3 |                3 | 6/2 = 3 |
| 7×7 |      4 |                3 | 7/2 = 3 |
+-----+--------+------------------+---------+

नोटिस कैसे N/2 परतों की संख्या से मेल खाती है जिन्हें घुमाए जाने की आवश्यकता है? कभी-कभी रोटेटेबल परतों की संख्या मैट्रिक्स में परतों की कुल संख्या से एक कम होती है। यह तब होता है जब अंतरतम परत केवल एक तत्व (यानी 1 × 1 मैट्रिक्स) से बनती है और इसलिए इसे घुमाने की आवश्यकता नहीं होती है। इसे बस नजरअंदाज कर दिया जाता है।

हमें मैट्रिक्स को घुमाने के लिए निस्संदेह इस जानकारी की आवश्यकता होगी, तो चलिए अब इसे जोड़ते हैं:

def rotate(matrix):
    size = len(matrix)
    # Rotatable layers only.
    layer_count = size / 2

अब हम जानते हैं कि परतें क्या हैं और उन परतों की संख्या का निर्धारण कैसे किया जाता है जिन्हें वास्तव में घूर्णन की आवश्यकता होती है, हम एक परत को कैसे अलग करते हैं ताकि हम इसे घुमा सकें? सबसे पहले, हम बाहरी परत से एक मैट्रिक्स का निरीक्षण करते हैं, अंदर की तरफ, सबसे भीतरी परत तक। 5 × 5 मैट्रिक्स में कुल तीन परतें होती हैं और दो परतों को घूमने की आवश्यकता होती है:

. . . . .
. x x x .
. x O x .
. x x x .
. . . . .

पहले कॉलम को देखें। सबसे बाहरी परत को परिभाषित करने वाले स्तंभों की स्थिति, मान लें कि हम 0 से गिनते हैं, 0 और 4 हैं:

+--------+-----------+
| Column | 0 1 2 3 4 |
+--------+-----------+
|        | . . . . . |
|        | . x x x . |
|        | . x O x . |
|        | . x x x . |
|        | . . . . . |
+--------+-----------+

0 और 4 सबसे बाहरी परत के लिए पंक्तियों की स्थिति भी हैं।

+-----+-----------+
| Row |           |
+-----+-----------+
|   0 | . . . . . |
|   1 | . x x x . |
|   2 | . x O x . |
|   3 | . x x x . |
|   4 | . . . . . |
+-----+-----------+

चौड़ाई और ऊंचाई समान होने के बाद से हमेशा यही स्थिति रहेगी। इसलिए हम एक लेयर के कॉलम और रो पोज़िशन्स को सिर्फ दो वैल्यूज़ (चार के बजाय) से परिभाषित कर सकते हैं।

दूसरी परत की ओर बढ़ते हुए, स्तंभों की स्थिति 1 और 3 है। और, हां, आपने अनुमान लगाया है, यह पंक्तियों के लिए समान है। यह समझना महत्वपूर्ण है कि अगली पंक्ति में अंदर की ओर बढ़ने पर हमें पंक्ति और स्तंभ स्थिति दोनों को बढ़ाना और घटाना पड़ता है।

+-----------+---------+---------+---------+
|   Layer   |  Rows   | Columns | Rotate? |
+-----------+---------+---------+---------+
| Outermost | 0 and 4 | 0 and 4 | Yes     |
| Inner     | 1 and 3 | 1 and 3 | Yes     |
| Innermost | 2       | 2       | No      |
+-----------+---------+---------+---------+

इसलिए, प्रत्येक परत का निरीक्षण करने के लिए, हम बढ़ते हुए और घटते हुए काउंटरों के साथ एक लूप चाहते हैं जो बाहरी परत से शुरू होकर अंदर की ओर जाने का प्रतिनिधित्व करते हैं। हम इसे 'लेयर लूप' कहेंगे।

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    for layer in range(0, layer_count):
        first = layer
        last = size - first - 1
        print 'Layer %d: first: %d, last: %d' % (layer, first, last)

# 5x5 matrix
matrix = [
    [ 0, 1, 2, 3, 4],
    [ 5, 6, 6, 8, 9],
    [10,11,12,13,14],
    [15,16,17,18,19],
    [20,21,22,23,24]
]

rotate(matrix)

किसी भी परतों की पंक्ति (पंक्ति और स्तंभ) के माध्यम से छोरों के ऊपर का कोड जिसे घूर्णन की आवश्यकता होती है।

Layer 0: first: 0, last: 4
Layer 1: first: 1, last: 3

अब हमारे पास एक लूप है जो प्रत्येक परत की पंक्तियों और स्तंभों की स्थिति प्रदान करता है। चर firstऔर lastपहली और आखिरी पंक्तियों और स्तंभों की सूचकांक स्थिति की पहचान करें। हमारी पंक्ति और स्तंभ तालिका पर वापस जाएं:

+--------+-----------+
| Column | 0 1 2 3 4 |
+--------+-----------+
|        | . . . . . |
|        | . x x x . |
|        | . x O x . |
|        | . x x x . |
|        | . . . . . |
+--------+-----------+

+-----+-----------+
| Row |           |
+-----+-----------+
|   0 | . . . . . |
|   1 | . x x x . |
|   2 | . x O x . |
|   3 | . x x x . |
|   4 | . . . . . |
+-----+-----------+

तो हम एक मैट्रिक्स की परतों के माध्यम से नेविगेट कर सकते हैं। अब हमें एक परत के भीतर नेविगेट करने के तरीके की आवश्यकता है ताकि हम उस परत के चारों ओर तत्वों को स्थानांतरित कर सकें। ध्यान दें, तत्व कभी भी एक परत से दूसरी परत पर 'कूदते' नहीं हैं, लेकिन वे अपनी संबंधित परतों में चलते हैं।

एक परत में प्रत्येक तत्व को घुमाने से पूरी परत घूम जाती है। मैट्रिक्स में सभी परतों को घुमाने से पूरी मैट्रिक्स घूम जाती है। यह वाक्य बहुत महत्वपूर्ण है, इसलिए कृपया आगे बढ़ने से पहले इसे समझने की पूरी कोशिश करें।

अब, हमें वास्तव में बढ़ते तत्वों का एक तरीका चाहिए, अर्थात प्रत्येक तत्व को घुमाएं, और बाद में परत, और अंततः मैट्रिक्स। सादगी के लिए, हम एक 3x3 मैट्रिक्स में वापस लौटेंगे - जिसमें एक सड़ने योग्य परत है।

0 1 2
3 4 5
6 7 8

हमारा लेयर लूप पहले और आखिरी कॉलम के इंडेक्स प्रदान करता है, साथ ही पहली और आखिरी पंक्तियाँ:

+-----+-------+
| Col | 0 1 2 |
+-----+-------+
|     | 0 1 2 |
|     | 3 4 5 |
|     | 6 7 8 |
+-----+-------+

+-----+-------+
| Row |       |
+-----+-------+
|   0 | 0 1 2 |
|   1 | 3 4 5 |
|   2 | 6 7 8 |
+-----+-------+

चूँकि हमारे मैट्रेस हमेशा चौकोर होते हैं, हमें सिर्फ दो वेरिएबल्स की जरूरत होती है, firstऔर last, चूंकि इंडेक्स पोज़िशन रो और कॉलम के लिए समान होती हैं।

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    # Our layer loop i=0, i=1, i=2
    for layer in range(0, layer_count):

        first = layer
        last = size - first - 1

        # We want to move within a layer here.

पहले और आखिरी चर आसानी से एक मैट्रिक्स के चार कोनों को संदर्भित करने के लिए इस्तेमाल किया जा सकता है। इसका कारण यह है कोनों खुद को के विभिन्न क्रमपरिवर्तन का उपयोग कर परिभाषित किया जा सकता firstहै और last(कोई घटाव, इसके अलावा के साथ या उन चर के ऑफसेट):

+---------------+-------------------+-------------+
| Corner        | Position          | 3x3 Values  |
+---------------+-------------------+-------------+
| top left      | (first, first)    | (0,0)       |
| top right     | (first, last)     | (0,2)       |
| bottom right  | (last, last)      | (2,2)       |
| bottom left   | (last, first)     | (2,0)       |
+---------------+-------------------+-------------+

इस कारण से, हम बाहरी चार कोनों पर अपना रोटेशन शुरू करते हैं - हम पहले उन परिक्रमा करेंगे। आइए उनके साथ प्रकाश डालें *

* 1 *
3 4 5
* 7 *

हम इसके अधिकार के *साथ प्रत्येक को स्वैप करना चाहते हैं *। तो चलिए आगे बढ़ते हैं कि हमारे विभिन्न कोनों का उपयोग करके परिभाषित हमारे कोनों का एक प्रिंट आउट firstऔर last:

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2
    for layer in range(0, layer_count):

        first = layer
        last = size - first - 1

        top_left = (first, first)
        top_right = (first, last)
        bottom_right = (last, last)
        bottom_left = (last, first)

        print 'top_left: %s' % (top_left)
        print 'top_right: %s' % (top_right)
        print 'bottom_right: %s' % (bottom_right)
        print 'bottom_left: %s' % (bottom_left)

matrix = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
]

rotate(matrix)

आउटपुट होना चाहिए:

top_left: (0, 0)
top_right: (0, 2)
bottom_right: (2, 2)
bottom_left: (2, 0)

अब हम अपने लेयर लूप में से प्रत्येक कोने को आसानी से स्वैप कर सकते हैं:

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2
    for layer in range(0, layer_count):

        first = layer
        last = size - first - 1

        top_left = matrix[first][first]
        top_right = matrix[first][last]
        bottom_right = matrix[last][last]
        bottom_left = matrix[last][first]

        # bottom_left -> top_left
        matrix[first][first] = bottom_left
        # top_left -> top_right
        matrix[first][last] = top_left
        # top_right -> bottom_right
        matrix[last][last] = top_right
        # bottom_right -> bottom_left
        matrix[last][first] = bottom_right


print_matrix(matrix)
print '---------'
rotate(matrix)
print_matrix(matrix)

कोनों को घुमाने से पहले मैट्रिक्स:

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

कोनों को घुमाने के बाद मैट्रिक्स:

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

महान! हमने मैट्रिक्स के प्रत्येक कोने को सफलतापूर्वक घुमाया है। लेकिन, हमने तत्वों को प्रत्येक परत के बीच में नहीं घुमाया है। स्पष्ट रूप से हमें एक परत के भीतर पुनरावृति के तरीके की आवश्यकता है।

समस्या यह है कि हमारे फ़ंक्शन में अब तक का एकमात्र लूप (हमारा लेयर लूप) है, जो प्रत्येक पुनरावृत्ति पर अगली परत पर जाता है। चूँकि हमारी मैट्रिक्स में केवल एक घूर्णन योग्य परत होती है, इसलिए लेयर लूप केवल कोनों को घुमाने के बाद बाहर निकल जाता है। आइए देखें कि बड़े, 5 × 5 मैट्रिक्स (जहां दो परतों को घुमाने की आवश्यकता होती है) के साथ क्या होता है। फ़ंक्शन कोड को छोड़ दिया गया है, लेकिन यह ऊपर जैसा है:

matrix = [
[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]
]
print_matrix(matrix)
print '--------------------'
rotate(matrix)
print_matrix(matrix)

आउटपुट है:

[20,  1,  2,  3,  0]
[ 5, 16,  7,  6,  9]
[10, 11, 12, 13, 14]
[15, 18, 17,  8, 19]
[24, 21, 22, 23,  4]

यह आश्चर्य की बात नहीं होनी चाहिए कि सबसे बाहरी परत के कोनों को घुमाया गया है, लेकिन, आप अगली परत के कोनों को भी नोटिस कर सकते हैं (अंदर की ओर) भी घुमाया गया है। यह समझ में आता है। हमने परतों के माध्यम से नेविगेट करने और प्रत्येक परत के कोनों को घुमाने के लिए कोड लिखा है। यह प्रगति की तरह लगता है, लेकिन दुर्भाग्य से हमें एक कदम वापस लेना चाहिए। जब तक पिछली (बाहरी) परत को पूरी तरह से घुमाया नहीं गया है, तब तक यह अगली परत पर अच्छा नहीं है। यही है, जब तक कि परत में प्रत्येक तत्व को घुमाया नहीं गया है। केवल कोनों को घुमाने से कुछ नहीं होगा!

एक गहरी सास लो। हमें एक और लूप चाहिए। एक नेस्टेड लूप कम नहीं। नया, नेस्टेड लूप, firstऔर lastचर का उपयोग करेगा , साथ ही एक परत के भीतर नेविगेट करने के लिए एक ऑफसेट। हम इस नए लूप को 'एलिमेंट लूप' कहेंगे। तत्व लूप शीर्ष पंक्ति के साथ प्रत्येक तत्व, दाईं ओर नीचे प्रत्येक तत्व, नीचे पंक्ति के साथ प्रत्येक तत्व और बाईं ओर प्रत्येक तत्व पर जाएगा।

  • शीर्ष पंक्ति के साथ आगे की ओर बढ़ने पर कॉलम इंडेक्स को बढ़ाना पड़ता है।
  • दाईं ओर नीचे जाने पर पंक्ति सूचकांक को बढ़ाना पड़ता है।
  • नीचे की ओर पीछे की ओर बढ़ने के लिए कॉलम इंडेक्स को घटाया जाना आवश्यक है।
  • बाईं ओर ऊपर ले जाने के लिए पंक्ति सूचकांक को घटाना आवश्यक है।

यह जटिल लगता है, लेकिन यह आसान है क्योंकि जितनी बार हम वृद्धि और वृद्धि को प्राप्त करते हैं उतनी बार मैट्रिक्स के सभी चार पक्षों के साथ समान रहता है। उदाहरण के लिए:

  • शीर्ष पंक्ति में 1 तत्व ले जाएँ।
  • दाईं ओर नीचे 1 तत्व ले जाएँ।
  • नीचे पंक्ति के साथ 1 तत्व पीछे की ओर ले जाएं।
  • बाईं ओर ऊपर 1 तत्व ले जाएँ।

इसका अर्थ है कि हम एक चर के साथ संयोजन में एक चर का उपयोग कर सकते हैं firstऔर lastएक परत के भीतर स्थानांतरित करने के लिए। यह नोट करने में मदद कर सकता है कि शीर्ष पंक्ति के नीचे और दाईं ओर नीचे बढ़ने पर दोनों को इंक्रीमेंट की आवश्यकता होती है। पीछे की ओर नीचे की ओर और बाईं ओर ऊपर की ओर ले जाने पर दोनों को घटने की आवश्यकता होती है।

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    # Move through layers (i.e. layer loop).
    for layer in range(0, layer_count):

            first = layer
            last = size - first - 1

            # Move within a single layer (i.e. element loop).
            for element in range(first, last):

                offset = element - first

                # 'element' increments column (across right)
                top_element = (first, element)
                # 'element' increments row (move down)
                right_side = (element, last)
                # 'last-offset' decrements column (across left)
                bottom = (last, last-offset)
                # 'last-offset' decrements row (move up)
                left_side = (last-offset, first)

                print 'top: %s' % (top)
                print 'right_side: %s' % (right_side)
                print 'bottom: %s' % (bottom)
                print 'left_side: %s' % (left_side)

अब हमें बस ऊपर से दाईं ओर, नीचे से दाईं ओर, नीचे से बाईं ओर, और बाईं ओर से ऊपर की ओर असाइन करने की आवश्यकता है। यह सब हम एक साथ लाना:

def rotate(matrix):
    size = len(matrix)
    layer_count = size / 2

    for layer in range(0, layer_count):
        first = layer
        last = size - first - 1

        for element in range(first, last):
            offset = element - first

            top = matrix[first][element]
            right_side = matrix[element][last]
            bottom = matrix[last][last-offset]
            left_side = matrix[last-offset][first]

            matrix[first][element] = left_side
            matrix[element][last] = top
            matrix[last][last-offset] = right_side
            matrix[last-offset][first] = bottom

मैट्रिक्स को देखते हुए:

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

हमारे rotateसमारोह में परिणाम:

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

मुझे शुरू में लगा कि "वाह, अब तक का सबसे अच्छा स्पष्टीकरण", लेकिन इसे एक-दो बार पढ़ने के बाद (यह सुनिश्चित करने के लिए कि मैं शब्दों के समुद्र में कुछ भी महत्वपूर्ण नहीं याद करता हूं), मेरी राय "आदमी, मैं इसे प्राप्त कर सकता हूं, में बदल सकता है" हम कृपया इसे आगे बढ़ाते रहें? " इस तरह के एक विस्तृत जवाब की रचना करने के लिए घंटों तक क्या करना चाहिए, इसके लिए अभी भी उत्कीर्ण है।
अभिजीत सरकार

1
@ अभिजितसरकर - वोटिंग के लिए धन्यवाद और मुझे उम्मीद है कि कम से कम कुछ छोटे तरीके से मदद मिली। बेशक, आप सही हैं, मेरा जवाब चिंताजनक है। हालांकि यह जानबूझकर जवाब के विशाल बहुमत के विपरीत था । जैसा कि मैंने अपने उत्तर की शुरुआत में कहा था: "इस उत्तर में, प्रमुख अवधारणाओं को दोहराया जाता है, गति धीमी और जानबूझकर दोहरावदार होती है।" यदि आपके पास संपादन हैं जो स्पष्टता और आवश्यक दोहराव रखते हैं, लेकिन शब्द गणना को कम करते हैं, तो मैं सुझाव के लिए बहुत खुला हूं। या अभी संपादित करें :)
जैक

@ जेक वास्तव में अच्छी व्याख्या। हालाँकि, मैं यह नहीं समझ सका, आप ऑफसेट = तत्व - प्रथम और अंतिम = आकार - प्रथम - 1 के साथ कैसे आए? यह समझने में कठिन समय बीत रहा है? इसके अलावा, पिछले ऑफसेट के रूप में ही ऑफसेट?
आशीषजम्श्रम

1
टीएल; डीआर:list(zip(*reversed(your_list_of_lists)))
बोरिस

127

अजगर:

rotated = list(zip(*original[::-1]))

और वामावर्त:

rotated_ccw = list(zip(*original))[::-1]

यह कैसे काम करता है:

zip(*original)नई सूची में सूचियों से संबंधित वस्तुओं को स्टैक करके 2d सरणियों की कुल्हाड़ियों को स्वैप करेगा। ( *ऑपरेटर तर्क में निहित सूचियों को वितरित करने के लिए फ़ंक्शन को बताता है)

>>> list(zip(*[[1,2,3],[4,5,6],[7,8,9]]))
[[1,4,7],[2,5,8],[3,6,9]]

[::-1]बयान पलट सरणी तत्वों (कृपया देखें विस्तारित स्लाइस या इस सवाल ):

>>> [[1,2,3],[4,5,6],[7,8,9]][::-1]
[[7,8,9],[4,5,6],[1,2,3]]

अंत में, दोनों के संयोजन के परिणामस्वरूप रोटेशन परिवर्तन होगा।

[::-1]मैट्रिक्स के विभिन्न स्तरों में सूचियों को रिवर्स करने के स्थान में परिवर्तन होगा।


3
मेरा मानना है कि पीटर Norvig से इस कोड का जन्म: norvig.com/python-iaq.html
जोसिप

आप मूल सूची की एक अतिरिक्त प्रतिलिपि बनाने से बचने के zip(*reversed(original))बजाय उपयोग कर सकते हैं zip(*original[::-1])
बोरिस

70

यहां एक है जो परिणाम को धारण करने के लिए एक पूरी तरह से नए सरणी का उपयोग करने के बजाय जगह में रोटेशन करता है। मैंने सरणी के आरंभीकरण को छोड़ दिया है और इसे प्रिंट कर रहा हूं। यह केवल वर्ग सरणियों के लिए काम करता है, लेकिन वे किसी भी आकार के हो सकते हैं। मेमोरी ओवरहेड सरणी के एक तत्व के आकार के बराबर है ताकि आप जितना चाहें उतना बड़े सरणी का रोटेशन कर सकें।

int a[4][4];
int n = 4;
int tmp;
for (int i = 0; i < n / 2; i++)
{
    for (int j = i; j < n - i - 1; j++)
    {
        tmp             = a[i][j];
        a[i][j]         = a[j][n-i-1];
        a[j][n-i-1]     = a[n-i-1][n-j-1];
        a[n-i-1][n-j-1] = a[n-j-1][i];
        a[n-j-1][i]     = tmp;
    }
}

मैं कम से कम एक बग देख सकता हूं। यदि आप कोड पोस्ट करने जा रहे हैं, तो इसका परीक्षण करें या कम से कम यह कहें कि आपने ऐसा नहीं किया है।
ह्यूज एलेन

1
कहाँ पे? इसे इंगित करें और मैं इसे ठीक कर दूंगा। मैंने इसका परीक्षण किया और इसने विषम और समान आकार दोनों पर ठीक काम किया।
डेगोरियम

2
इसका सुंदर समाधान है। यदि उद्देश्य के लिए मन इस तरह के करतब कर सकता है। O (n2) से O (1) तक
MoveFast

2
यह ओ (1) नहीं है; यह अभी भी हे (n ^ 2)
duma

11
इसकी O (n ^ 2) मेमोरी O (1) के साथ है।
नील

38

यहां अच्छे कोड के टन हैं, लेकिन मैं सिर्फ दिखाना चाहता हूं कि ज्यामितीय रूप से क्या हो रहा है ताकि आप कोड तर्क को थोड़ा बेहतर समझ सकें। यहां बताया गया है कि मैं कैसे इस से संपर्क करूंगा।

सबसे पहले, ट्रांसपोज़िशन के साथ इसे भ्रमित न करें जो बहुत आसान है ..

बेसिक विचार यह है कि इसे परतों के रूप में माना जाए और हम एक बार में एक परत को घुमाते हैं।

हम एक 4x4 है

1   2   3   4
5   6   7   8
9   10  11  12
13  14  15  16

90 के बाद हम इसे दक्षिणावर्त घुमाते हैं

13  9   5   1
14  10  6   2   
15  11  7   3
16  12  8   4

तो चलिए इसका विघटन करते हैं, पहले हम 4 कोनों को अनिवार्य रूप से घुमाते हैं

1           4


13          16

फिर हम निम्नलिखित हीरे को घुमाते हैं, जो आस्क्यू की तरह होता है

    2
            8
9       
        15

और फिर दूसरा तिरछा हीरा

        3
5           
            12
    14

इसलिए कि बाहरी छोर की देखभाल इतनी अनिवार्य रूप से की जाती है कि हम उस समय तक एक खोल को खोलते हैं

अंत में मध्य वर्ग (या यदि यह सिर्फ अंतिम तत्व है जो आगे नहीं बढ़ता है)

6   7
10  11

इसलिए अब प्रत्येक परत के सूचकांकों को समझें, मान लें कि हम हमेशा सबसे बाहरी परत के साथ काम करते हैं, हम कर रहे हैं

[0,0] -> [0,n-1], [0,n-1] -> [n-1,n-1], [n-1,n-1] -> [n-1,0], and [n-1,0] -> [0,0]
[0,1] -> [1,n-1], [1,n-2] -> [n-1,n-2], [n-1,n-2] -> [n-2,0], and [n-2,0] -> [0,1]
[0,2] -> [2,n-2], [2,n-2] -> [n-1,n-3], [n-1,n-3] -> [n-3,0], and [n-3,0] -> [0,2]

तब तक और इसी तरह जब तक हम किनारे से आधे नहीं होते

तो सामान्य तौर पर पैटर्न है

[0,i] -> [i,n-i], [i,n-i] -> [n-1,n-(i+1)], [n-1,n-(i+1)] -> [n-(i+1),0], and [n-(i+1),0] to [0,i]

इसका क्या मतलब है "आधे रास्ते से किनारे"? मुझे एन / 2 तक बहुत सारे एल्गोरिदम लूपिंग दिखाई देते हैं और अन्य लोग एन को लूप करते हैं, लेकिन मैं यह नहीं देख सकता कि एन / 2 कहां से आ रहा है।
पीडीएन

मेरा मानना ​​है कि कोडिंग इंटरव्यू क्रैक करने में दिए गए इसका एक ही समाधान है। लेकिन मुझे स्टेप बाई स्टेप स्पष्टीकरण पसंद है। बहुत अच्छा और संपूर्ण।
नेपचस्टर

@PDN यह उत्तर इसे विस्तार से बताता है।
मथियास ब्यानेन्स

35

जैसा कि मैंने अपनी पिछली पोस्ट में कहा था, यहाँ C # में कुछ कोड है जो किसी भी आकार के मैट्रिक्स के लिए O (1) मैट्रिक्स रोटेशन लागू करता है। संक्षिप्तता और पठनीयता के लिए कोई त्रुटि जाँच या श्रेणी जाँच नहीं है। कोड:

static void Main (string [] args)
{
  int [,]
    //  create an arbitrary matrix
    m = {{0, 1}, {2, 3}, {4, 5}};

  Matrix
    //  create wrappers for the data
    m1 = new Matrix (m),
    m2 = new Matrix (m),
    m3 = new Matrix (m);

  //  rotate the matricies in various ways - all are O(1)
  m1.RotateClockwise90 ();
  m2.Rotate180 ();
  m3.RotateAnitclockwise90 ();

  //  output the result of transforms
  System.Diagnostics.Trace.WriteLine (m1.ToString ());
  System.Diagnostics.Trace.WriteLine (m2.ToString ());
  System.Diagnostics.Trace.WriteLine (m3.ToString ());
}

class Matrix
{
  enum Rotation
  {
    None,
    Clockwise90,
    Clockwise180,
    Clockwise270
  }

  public Matrix (int [,] matrix)
  {
    m_matrix = matrix;
    m_rotation = Rotation.None;
  }

  //  the transformation routines
  public void RotateClockwise90 ()
  {
    m_rotation = (Rotation) (((int) m_rotation + 1) & 3);
  }

  public void Rotate180 ()
  {
    m_rotation = (Rotation) (((int) m_rotation + 2) & 3);
  }

  public void RotateAnitclockwise90 ()
  {
    m_rotation = (Rotation) (((int) m_rotation + 3) & 3);
  }

  //  accessor property to make class look like a two dimensional array
  public int this [int row, int column]
  {
    get
    {
      int
        value = 0;

      switch (m_rotation)
      {
      case Rotation.None:
        value = m_matrix [row, column];
        break;

      case Rotation.Clockwise90:
        value = m_matrix [m_matrix.GetUpperBound (0) - column, row];
        break;

      case Rotation.Clockwise180:
        value = m_matrix [m_matrix.GetUpperBound (0) - row, m_matrix.GetUpperBound (1) - column];
        break;

      case Rotation.Clockwise270:
        value = m_matrix [column, m_matrix.GetUpperBound (1) - row];
        break;
      }

      return value;
    }

    set
    {
      switch (m_rotation)
      {
      case Rotation.None:
        m_matrix [row, column] = value;
        break;

      case Rotation.Clockwise90:
        m_matrix [m_matrix.GetUpperBound (0) - column, row] = value;
        break;

      case Rotation.Clockwise180:
        m_matrix [m_matrix.GetUpperBound (0) - row, m_matrix.GetUpperBound (1) - column] = value;
        break;

      case Rotation.Clockwise270:
        m_matrix [column, m_matrix.GetUpperBound (1) - row] = value;
        break;
      }
    }
  }

  //  creates a string with the matrix values
  public override string ToString ()
  {
    int
      num_rows = 0,
      num_columns = 0;

    switch (m_rotation)
    {
    case Rotation.None:
    case Rotation.Clockwise180:
      num_rows = m_matrix.GetUpperBound (0);
      num_columns = m_matrix.GetUpperBound (1);
      break;

    case Rotation.Clockwise90:
    case Rotation.Clockwise270:
      num_rows = m_matrix.GetUpperBound (1);
      num_columns = m_matrix.GetUpperBound (0);
      break;
    }

    StringBuilder
      output = new StringBuilder ();

    output.Append ("{");

    for (int row = 0 ; row <= num_rows ; ++row)
    {
      if (row != 0)
      {
        output.Append (", ");
      }

      output.Append ("{");

      for (int column = 0 ; column <= num_columns ; ++column)
      {
        if (column != 0)
        {
          output.Append (", ");
        }

        output.Append (this [row, column].ToString ());
      }

      output.Append ("}");
    }

    output.Append ("}");

    return output.ToString ();
  }

  int [,]
    //  the original matrix
    m_matrix;

  Rotation
    //  the current view of the matrix
    m_rotation;
}

ठीक है, मैं अपना हाथ ऊपर रखूंगा, यह वास्तव में घुमाते समय मूल सरणी में कोई संशोधन नहीं करता है। लेकिन, एक OO प्रणाली में जब तक कि यह वर्ग के ग्राहकों को घुमाया जाता है, तब तक कोई फर्क नहीं पड़ता कि वस्तु दिखती है। फिलहाल, मैट्रिक्स क्लास मूल सरणी डेटा के संदर्भ का उपयोग करता है इसलिए एम 1 और एम 3 को बदलने से एम 1 का कोई भी मूल्य बदल जाएगा। नया सरणी बनाने के लिए और इसे मानों की प्रतिलिपि बनाने के लिए कंस्ट्रक्टर के लिए एक छोटा सा बदलाव इसे छाँट देगा।


4
वाहवाही! यह एक बहुत अच्छा समाधान है और मुझे नहीं पता कि यह स्वीकृत उत्तर क्यों नहीं है।
मार्टिनेटाइम

@ स्मार्टिनैटाइम: शायद इसलिए क्योंकि यह 5 गुना बड़ा है
टॉड

@ लोड: ठीक है, कोड लिखना हमेशा प्रतिस्पर्धा की आवश्यकताओं के बीच एक व्यापार है: गति, आकार, लागत, आदि
स्किज़

15
सच ... एक और समस्या यह तथ्य है कि मैट्रिक्स वास्तव में घुमाया नहीं जाता है, लेकिन 'बस समय में' घुमाया जाता है। जो कुछ तत्वों तक पहुँचने के लिए बहुत अच्छा है, लेकिन अगर यह मैट्रिक्स गणना या छवि हेरफेर में उपयोग किया गया था तो भयानक होगा। इसलिए ओ (1) कहना वास्तव में उचित नहीं है।
टॉड

23

जबकि जगह में डेटा को घुमाने के लिए आवश्यक हो सकता है (शायद शारीरिक रूप से संग्रहीत प्रतिनिधित्व को अद्यतन करने के लिए), यह सरणी पहुंच पर अप्रत्यक्षता की परत को जोड़ने के लिए सरल और संभवतः अधिक प्रदर्शनकारी हो सकता है, शायद एक इंटरफ़ेस:

interface IReadableMatrix
{
    int GetValue(int x, int y);
}

यदि आपका Matrixपहले से ही इस इंटरफ़ेस को लागू करता है, तो इसे इस तरह से डेकोरेटर वर्ग के माध्यम से घुमाया जा सकता है :

class RotatedMatrix : IReadableMatrix
{
    private readonly IReadableMatrix _baseMatrix;

    public RotatedMatrix(IReadableMatrix baseMatrix)
    {
        _baseMatrix = baseMatrix;
    }

    int GetValue(int x, int y)
    {
        // transpose x and y dimensions
        return _baseMatrix(y, x);
    }
}

घूर्णन + 90 / -90 / 180 डिग्री, क्षैतिज रूप से / लंबवत रूप से फ़्लिप करना और स्केलिंग करना सभी इस फैशन में भी हासिल किया जा सकता है।

प्रदर्शन को आपके विशिष्ट परिदृश्य में मापा जाना चाहिए। हालाँकि O (n ^ 2) ऑपरेशन को अब O (1) कॉल से बदल दिया गया है। यह एक वर्चुअल मेथड कॉल है डायरेक्ट एरे एक्सेस की तुलना में धीमी है, इसलिए यह इस बात पर निर्भर करता है कि रोटेशन के बाद कितनी बार रोटेट की गई सरणी का उपयोग किया जाता है। यदि यह एक बार उपयोग किया जाता है, तो यह दृष्टिकोण निश्चित रूप से जीत जाएगा। यदि इसे घुमाया जाता है, तो लंबे समय तक चलने वाली प्रणाली में उपयोग किया जाता है, तो इन-प्लेस रोटेशन बेहतर प्रदर्शन कर सकता है। यह भी निर्भर करता है कि आप अप-फ्रंट कॉस्ट को स्वीकार कर सकते हैं या नहीं।

सभी प्रदर्शन मुद्दों के साथ के रूप में, उपाय, माप, माप!


1
+1 ... और यदि मैट्रिक्स वास्तव में बड़ा है और आप केवल कुछ तत्वों (विरल उपयोग) का उपयोग करते हैं तो यह और भी प्रभावी है
लोथर

16
इसे O (1) समय समाधान कहना थोड़ा अनुचित लगता है। ओपी द्वारा पेश की गई समस्या को हल करने के लिए अभी भी O (n ^ 2) समय लगेगा। इतना ही नहीं, यह समस्या को हल नहीं करेगा क्योंकि यह स्थानान्तरण लौटाता है । दिए गए उदाहरण में समाधान के रूप में संक्रमण नहीं है।
व्लाद इम्पाला

5
अब, यदि आप चाहते थे कि मैट्रिक्स के पहले 3 तत्व थे, तो यह एक अच्छा समाधान है, लेकिन समस्या पूरी तरह से परिवर्तित मैट्रिक्स को पुनः प्राप्त करना है (अर्थात यह मानते हुए कि आपको सभी मैट्रिक्स तत्वों की आवश्यकता है)। इस O (1) को कॉल करना एल्गोरिथ्म एनालिसिस का क्रेडिट डिफॉल्ट स्वैप तरीका है - आपने समस्या का समाधान नहीं किया है, आपने इसे किसी और को दिया है :)
Ana Betts

4
@ पाओल बेट्स: मुझे आपकी बात अच्छी लगती है, लेकिन जैसा मैंने ऊपर टिप्पणी में लिखा था, भले ही आपके पास वास्तव में मैट्रिक्स ट्रांसपोज़्ड हो, फिर भी आपको लूप लिखना होगा यदि आप मूल्यों को पढ़ना चाहते हैं। इसलिए मैट्रिक्स से सभी मानों को पढ़ना हमेशा O (N ^ 2) होता है। यहां अंतर यह है कि यदि आप ट्रांसजेंड, रोटेट, स्केल, स्केल फिर से, आदि करते हैं, तो आप अभी भी केवल एक बार O (N ^ 2) को हिट करते हैं। जैसा कि मैंने कहा, यह हमेशा सबसे अच्छा समाधान नहीं है, लेकिन कई मामलों में यह उचित और सार्थक है। ओपी एक जादू समाधान की तलाश में लग रहा था, और यह उतना ही करीब है जितना आपको मिलेगा।
ड्रू नोकें

9
मुझे यह उत्तर पसंद है, लेकिन मैं कुछ कहना चाहता हूं। सजाए गए मैट्रिक्स को प्रिंट करना (और सामान्य रूप से अन्य अनुक्रमिक रीडिंग करना) एक मैट्रिक्स के समान करने की तुलना में बहुत धीमा हो सकता है जिसे मेमोरी में घुमाया गया है, और यह सिर्फ वर्चुअल विधि कॉल के कारण नहीं है। एक बड़े मैट्रिक्स के लिए, आप "भर" के बजाय "नीचे" पढ़कर प्राप्त की जाने वाली कैश मिस की संख्या में भारी वृद्धि करने जा रहे हैं।
माइक डेनियल

18

यह जावा में इसका एक बेहतर संस्करण है: मैंने इसे एक मैट्रिक्स के लिए एक अलग चौड़ाई और ऊंचाई के साथ बनाया है

  • एच यहां घूर्णन के बाद मैट्रिक्स की ऊंचाई है
  • डब्ल्यू यहां घूर्णन के बाद मैट्रिक्स की चौड़ाई है

 

public int[][] rotateMatrixRight(int[][] matrix)
{
    /* W and H are already swapped */
    int w = matrix.length;
    int h = matrix[0].length;
    int[][] ret = new int[h][w];
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            ret[i][j] = matrix[w - j - 1][i];
        }
    }
    return ret;
}


public int[][] rotateMatrixLeft(int[][] matrix)
{
    /* W and H are already swapped */
    int w = matrix.length;
    int h = matrix[0].length;   
    int[][] ret = new int[h][w];
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            ret[i][j] = matrix[j][h - i - 1];
        }
    }
    return ret;
}

यह कोड Nick Berardi की पोस्ट पर आधारित है।


धन्यवाद। यह यहाँ स्पष्ट जावा कोड था। प्रश्न - [w - j - 1] भाग के साथ आप / निक कैसे आए? @ वेटिंग के जवाब को देखकर मैं देख सकता हूं कि आप इंडक्शन / सॉल्विंग उदाहरणों के माध्यम से कैसे प्राप्त कर सकते हैं। अगर यह कैसे प्राप्त किया गया था या मैट्रिस से संबंधित किसी गणितीय सिद्धांत पर आधारित है तो बस सोच रहा था।
क्वेस्ट मोंगर

17

रूबी तरह: .transpose.map &:reverse


1
यह उससे भी सरल है: array.reverse.transposeएक सरणी को दक्षिणावर्त array.transpose.reverseघुमाता है , जबकि इसे वामावर्त घुमाता है। इसकी कोई आवश्यकता नहीं है map
जियोर्गी गाज़िरिश्वली

13

पहले से ही बहुत सारे उत्तर हैं, और मुझे ओ (1) समय जटिलता के दो दावे मिले। असली हे (1) एल्गोरिथ्म सरणी भंडारण अछूता छोड़ देते हैं, और बदल कैसे आप सूचकांक उसके तत्वों के लिए है। यहां लक्ष्य यह है कि यह अतिरिक्त मेमोरी का उपभोग नहीं करता है, न ही डेटा को पुनरावृत्त करने के लिए अतिरिक्त समय की आवश्यकता होती है।

90, -90 और 180 डिग्री के घुमाव सरल परिवर्तन हैं जो तब तक किए जा सकते हैं जब तक आप जानते हैं कि आपके 2D सरणी में कितनी पंक्तियाँ और स्तंभ हैं; किसी भी वेक्टर को 90 डिग्री तक घुमाने के लिए, कुल्हाड़ियों को स्वैप करें और Y अक्ष को नकारें। -90 डिग्री के लिए, एक्सिस को स्वैप करें और एक्स अक्ष को नकारात्मक करें। 180 डिग्री के लिए, स्वैप किए बिना दोनों कुल्हाड़ियों को नकारें।

आगे परिवर्तन संभव हैं, जैसे कि क्षैतिज रूप से और / या अनुलंब रूप से कुल्हाड़ियों को स्वतंत्र रूप से नकारते हुए प्रतिबिंबित करना।

यह उदाहरण के तौर पर एक्‍सर विधि से किया जा सकता है। नीचे दिए गए उदाहरण जावास्क्रिप्ट कार्य हैं, लेकिन अवधारणा सभी भाषाओं पर समान रूप से लागू होती हैं।

 // Get an array element in column/row order
 var getArray2d = function(a, x, y) {
   return a[y][x];
 };

 //demo
 var arr = [
   [5, 4, 6],
   [1, 7, 9],
   [-2, 11, 0],
   [8, 21, -3],
   [3, -1, 2]
 ];

 var newarr = [];
 arr[0].forEach(() => newarr.push(new Array(arr.length)));

 for (var i = 0; i < newarr.length; i++) {
   for (var j = 0; j < newarr[0].length; j++) {
     newarr[i][j] = getArray2d(arr, i, j);
   }
 }
 console.log(newarr);

// Get an array element rotated 90 degrees clockwise
function getArray2dCW(a, x, y) {
  var t = x;
  x = y;
  y = a.length - t - 1;
  return a[y][x];
}

//demo
var arr = [
  [5, 4, 6],
  [1, 7, 9],
  [-2, 11, 0],
  [8, 21, -3],
  [3, -1, 2]
];

var newarr = [];
arr[0].forEach(() => newarr.push(new Array(arr.length)));

for (var i = 0; i < newarr[0].length; i++) {
  for (var j = 0; j < newarr.length; j++) {
    newarr[j][i] = getArray2dCW(arr, i, j);
  }
}
console.log(newarr);

// Get an array element rotated 90 degrees counter-clockwise
function getArray2dCCW(a, x, y) {
  var t = x;
  x = a[0].length - y - 1;
  y = t;
  return a[y][x];
}

//demo
var arr = [
  [5, 4, 6],
  [1, 7, 9],
  [-2, 11, 0],
  [8, 21, -3],
  [3, -1, 2]
];

var newarr = [];
arr[0].forEach(() => newarr.push(new Array(arr.length)));

for (var i = 0; i < newarr[0].length; i++) {
  for (var j = 0; j < newarr.length; j++) {
    newarr[j][i] = getArray2dCCW(arr, i, j);
  }
}
console.log(newarr);

// Get an array element rotated 180 degrees
function getArray2d180(a, x, y) {
  x = a[0].length - x - 1;
  y = a.length - y - 1;
  return a[y][x];
}

//demo
var arr = [
  [5, 4, 6],
  [1, 7, 9],
  [-2, 11, 0],
  [8, 21, -3],
  [3, -1, 2]
];

var newarr = [];
arr.forEach(() => newarr.push(new Array(arr[0].length)));

for (var i = 0; i < newarr[0].length; i++) {
  for (var j = 0; j < newarr.length; j++) {
    newarr[j][i] = getArray2d180(arr, i, j);
  }
}
console.log(newarr);

यह कोड नेस्टेड सरणियों की एक सरणी मानता है, जहां प्रत्येक आंतरिक सरणी एक पंक्ति है।

विधि आपको तत्वों को पढ़ने (या लिखने) (यादृच्छिक क्रम में भी) की अनुमति देती है जैसे कि सरणी को घुमाया या रूपांतरित किया गया हो। अब बस कॉल करने के लिए सही फ़ंक्शन चुनें, शायद संदर्भ से, और दूर आप जाएं!

अभिगम विधियों के माध्यम से योगात्मक (और गैर-विनाशकारी) परिवर्तनों को लागू करने के लिए अवधारणा को बढ़ाया जा सकता है। जिसमें मनमाना कोण घुमाव और स्केलिंग शामिल है।


हालांकि इनमें से कोई भी वास्तव में मूल सरणी से नहीं घुमाया गया है। पहला परिणाम, अंतिम परिणाम केवल ट्रांसपोज़्ड है। दूसरा एक, आप सिर्फ पंक्तियों को फेरते हुए या क्षैतिज केंद्र में प्रतिबिम्बित दिखाई देते हैं। तीसरा, आपने केवल पंक्तियों को उलट दिया है और चौथे को भी स्थानांतरित कर दिया गया है। जिनमें से कोई भी वास्तव में "घुमाया गया" नहीं था।
SM177Y

बाद के दो उदाहरणों में कुछ कीड़े हैं। ठीक करने के लिए तुच्छ। मैं स्पष्ट रूप से कहा कि इस समाधान है नहीं एक में जगह रोटेशन। यह एक परिवर्तन कार्य है, जो इसे आलसी पुनरावृत्ति के लिए उपयुक्त बनाता है।
जेसन ओस्टर

सिवाय इसके कि कोई रोटेशन नहीं है, इसलिए आपने वास्तव में ओपी से क्या जवाब दिया।
SM177Y

@ SM177Y एक अन्य संपादक ने मेरे जवाब में गैर-कार्यशील उदाहरण कोड जोड़ा। मैं देख सकता हूं कि आप इसे कैसे भ्रमित कर रहे थे। मैंने चलना छोरों में कीड़े तय कर दिए हैं। प्रदान किए गए कार्य वास्तव में सरणियों में डेटा को "घुमाते" हैं।
जेसन ओस्टर

इसके अलावा महत्वपूर्ण विवरण यह है कि उदाहरण कोड वास्तव में मेरे द्वारा प्रदान किए गए मूल उत्तर को धो देता है, जो रैखिक स्थान-समय जटिलता समाधानों पर कार्यात्मक परिवर्तनों की शक्ति का वर्णन करने की कोशिश कर रहा था। एक कार्यात्मक परिवर्तन के साथ आप पहले से ही पुनरावृत्ति कर रहे हैं या अन्यथा सरणी तत्वों तक पहुँच प्राप्त कर रहे हैं , इसलिए परिवर्तन को निरंतर स्थान और समय की जटिलता के अर्थ में "मुक्त" माना जाता है।
जेसन ओस्टर

10

कुछ लोगों ने पहले ही उदाहरण प्रस्तुत कर दिए हैं, जिसमें एक नई सारणी बनाना शामिल है।

विचार करने के लिए कुछ अन्य बातें:

(ए) वास्तव में डेटा को स्थानांतरित करने के बजाय, बस "घुमाए गए" सरणी को अलग तरीके से पार करें।

(b) रोटेशन को इन-प्लेस करना थोड़ा पेचीदा हो सकता है। आपको थोड़ी सी खरोंच जगह (शायद एक पंक्ति या स्तंभ के आकार के बराबर) की आवश्यकता होगी। इन-प्लेस ट्रांज़ोज़ ( http://doi.acm.org/10.1145/355719.355729 ) करने के बारे में एक प्राचीन ACM पेपर है , लेकिन उनका उदाहरण कोड गंदा गोटो से भरा FORTRAN है।

परिशिष्ट:

http://doi.acm.org/10.1145/355611.355612 एक और, माना जाता है कि बेहतर, इन-प्लेस पारगमन एल्गोरिथ्म।


मैं इससे सहमत हु। एक विधि है जो स्रोत डेटा और "घुमाए गए" डेटा के बीच अनुवाद का निर्धारण करते हैं।
१६:०६ पर मार्टिनाटाइम

8

निक का जवाब केवल एक छोटे संशोधन के साथ एक NxM सरणी के लिए काम करेगा (जैसा कि एक NxN के विपरीत)।

string[,] orig = new string[n, m];
string[,] rot = new string[m, n];

...

for ( int i=0; i < n; i++ )
  for ( int j=0; j < m; j++ )
    rot[j, n - i - 1] = orig[i, j];

इस बारे में सोचने का एक तरीका यह है कि आपने धुरी के केंद्र (0,0) को ऊपरी बाएँ कोने से ऊपरी दाएँ कोने में स्थानांतरित कर दिया है। आप बस एक से दूसरे में ट्रांसपोज़ हो रहे हैं।


6

समय - O (N), अंतरिक्ष - O (1)

public void rotate(int[][] matrix) {
    int n = matrix.length;
    for (int i = 0; i < n / 2; i++) {
        int last = n - 1 - i;
        for (int j = i; j < last; j++) {
            int top = matrix[i][j];
            matrix[i][j] = matrix[last - j][i];
            matrix[last - j][i] = matrix[last][last - j];
            matrix[last][last - j] = matrix[j][last];
            matrix[j][last] = top;
        }
    }
}

यह O (1) नहीं है। यह O (n) है।
जेसन ओस्टर

@ जैसनऑस्टर का मानना ​​है कि यह ओ (1) स्थान है, क्योंकि इसमें कोई अतिरिक्त स्थान नहीं है।
ffledgling

@ गलती मेरी गलती है। ओ (1) अंतरिक्ष जटिलता, हाँ। ओ (एन) समय जटिलता।
जेसन ओस्टर

अंतरिक्ष जटिलता O (n) भी है। अंतरिक्ष जटिलता में इनपुट चर आकार का स्थान शामिल होना चाहिए। careercup.com/question?id=14952322
जेसन

एक वामावर्त रोटेशन के लिए मैं इसे कैसे संशोधित कर सकता हूं?
एमडी एक्सएफ

5

यहां मेरा रूबी संस्करण है (ध्यान दें कि मान समान नहीं हैं, लेकिन यह अभी भी वर्णित के रूप में घूमता है)।

def rotate(matrix)
  result = []
  4.times { |x|
    result[x] = []
    4.times { |y|
      result[x][y] = matrix[y][3 - x]
    }
  }

  result
end

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

def print_matrix(matrix)
  4.times { |y|
    4.times { |x|
      print "#{matrix[x][y]} "
    }
    puts ""
  }
end

print_matrix(matrix)
puts ""
print_matrix(rotate(matrix))

उत्पादन:

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

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

4

यहाँ एक इन-स्पेस रोटेट विधि, जावा द्वारा, केवल वर्ग के लिए। गैर-वर्ग 2d सरणी के लिए, आपको वैसे भी नया सरणी बनाना होगा।

private void rotateInSpace(int[][] arr) {
    int z = arr.length;
    for (int i = 0; i < z / 2; i++) {
        for (int j = 0; j < (z / 2 + z % 2); j++) {
            int x = i, y = j;
            int temp = arr[x][y];
            for (int k = 0; k < 4; k++) {
                int temptemp = arr[y][z - x - 1];
                arr[y][z - x - 1] = temp;
                temp = temptemp;

                int tempX = y;
                y = z - x - 1;
                x = tempX;
            }
        }
    }
}

नया सरणी बनाकर किसी भी आकार 2d सरणी को घुमाने के लिए कोड:

private int[][] rotate(int[][] arr) {
    int width = arr[0].length;
    int depth = arr.length;
    int[][] re = new int[width][depth];
    for (int i = 0; i < depth; i++) {
        for (int j = 0; j < width; j++) {
            re[j][depth - i - 1] = arr[i][j];
        }
    }
    return re;
}

3

जावास्क्रिप्ट में डिम्पल के +90 स्यूडोकोड (उदाहरण के लिए फिर प्रत्येक पंक्ति को उल्टा करें) का कार्यान्वयन:

function rotate90(a){
  // transpose from http://www.codesuck.com/2012/02/transpose-javascript-array-in-one-line.html
  a = Object.keys(a[0]).map(function (c) { return a.map(function (r) { return r[c]; }); });
  // row reverse
  for (i in a){
    a[i] = a[i].reverse();
  }
  return a;
}

3

आप इसे 3 आसान चरणों में कर सकते हैं :

1 ) मान लीजिए कि हमारे पास एक मैट्रिक्स है

   1 2 3
   4 5 6
   7 8 9

2 ) मैट्रिक्स का स्थानान्तरण लें

   1 4 7
   2 5 8
   3 6 9

3 ) इंटरचेंज पंक्तियों को घुमाए गए मैट्रिक्स प्राप्त करने के लिए

   3 6 9
   2 5 8
   1 4 7

इसके लिए जावा स्रोत कोड :

public class MyClass {

    public static void main(String args[]) {
        Demo obj = new Demo();
        /*initial matrix to rotate*/
        int[][] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
        int[][] transpose = new int[3][3]; // matrix to store transpose

        obj.display(matrix);              // initial matrix

        obj.rotate(matrix, transpose);    // call rotate method
        System.out.println();
        obj.display(transpose);           // display the rotated matix
    }
}

class Demo {   
    public void rotate(int[][] mat, int[][] tran) {

        /* First take the transpose of the matrix */
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat.length; j++) {
                tran[i][j] = mat[j][i]; 
            }
        }

        /*
         * Interchange the rows of the transpose matrix to get rotated
         * matrix
         */
        for (int i = 0, j = tran.length - 1; i != j; i++, j--) {
            for (int k = 0; k < tran.length; k++) {
                swap(i, k, j, k, tran);
            }
        }
    }

    public void swap(int a, int b, int c, int d, int[][] arr) {
        int temp = arr[a][b];
        arr[a][b] = arr[c][d];
        arr[c][d] = temp;    
    }

    /* Method to display the matrix */
    public void display(int[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }
}

आउटपुट:

1 2 3 
4 5 6 
7 8 9 

3 6 9 
2 5 8 
1 4 7 

2

यह मेरा कार्यान्वयन है, C, O (1) मेमोरी जटिलता में, स्थान रोटेशन में, 90 डिग्री दक्षिणावर्त:

#include <stdio.h>

#define M_SIZE 5

static void initMatrix();
static void printMatrix();
static void rotateMatrix();

static int m[M_SIZE][M_SIZE];

int main(void){
    initMatrix();
    printMatrix();
    rotateMatrix();
    printMatrix();

    return 0;
}

static void initMatrix(){
    int i, j;

    for(i = 0; i < M_SIZE; i++){
        for(j = 0; j < M_SIZE; j++){
            m[i][j] = M_SIZE*i + j + 1;
        }
    }
}

static void printMatrix(){
    int i, j;

    printf("Matrix\n");
    for(i = 0; i < M_SIZE; i++){
        for(j = 0; j < M_SIZE; j++){
            printf("%02d ", m[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

static void rotateMatrix(){
    int r, c;

    for(r = 0; r < M_SIZE/2; r++){
        for(c = r; c < M_SIZE - r - 1; c++){
            int tmp = m[r][c];

            m[r][c] = m[M_SIZE - c - 1][r];
            m[M_SIZE - c - 1][r] = m[M_SIZE - r - 1][M_SIZE - c - 1];
            m[M_SIZE - r - 1][M_SIZE - c - 1] = m[c][M_SIZE - r - 1];
            m[c][M_SIZE - r - 1] = tmp;
        }
    }
}

2

यहाँ जावा संस्करण है:

public static void rightRotate(int[][] matrix, int n) {
    for (int layer = 0; layer < n / 2; layer++) {
        int first = layer;
        int last = n - 1 - first;
        for (int i = first; i < last; i++) {
           int offset = i - first;
           int temp = matrix[first][i];
           matrix[first][i] = matrix[last-offset][first];
           matrix[last-offset][first] = matrix[last][last-offset];
           matrix[last][last-offset] = matrix[i][last];
           matrix[i][last] = temp;
        }
    }
}

विधि सबसे पहले राउटर की परत को घुमाती है, फिर आंतरिक स्तर पर स्क्वीलीली ले जाती है।


2

रैखिक बिंदु से, मैट्रिसेस पर विचार करें:

    1 2 3        0 0 1
A = 4 5 6    B = 0 1 0
    7 8 9        1 0 0

अब A ट्रांसपोज़ करें

     1 4 7
A' = 2 5 8
     3 6 9

और ए की क्रिया को 'बी पर बी या बी पर ए' मानें।
क्रमश:

      7 4 1          3 6 9
A'B = 8 5 2    BA' = 2 5 8
      9 6 3          1 4 7

यह किसी भी nxn मैट्रिक्स के लिए विस्तार योग्य है। और इस अवधारणा को जल्दी से कोड में लागू करना:

void swapInSpace(int** mat, int r1, int c1, int r2, int c2)
{
    mat[r1][c1] ^= mat[r2][c2];
    mat[r2][c2] ^= mat[r1][c1];
    mat[r1][c1] ^= mat[r2][c2];
}

void transpose(int** mat, int size)
{
    for (int i = 0; i < size; i++)
    {
        for (int j = (i + 1); j < size; j++)
        {
            swapInSpace(mat, i, j, j, i);
        }
    }
}

void rotate(int** mat, int size)
{
    //Get transpose
    transpose(mat, size);

    //Swap columns
    for (int i = 0; i < size / 2; i++)
    {
        for (int j = 0; j < size; j++)
        {
            swapInSpace(mat, i, j, size - (i + 1), j);
        }
    }
}

2

सी # कोड को घुमाने के लिए [एन, एम] 2 डी सरणियां 90 डिग्री सही

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MatrixProject
{
    // mattrix class

    class Matrix{
        private int rows;
        private int cols;
        private int[,] matrix;

        public Matrix(int n){
            this.rows = n;
            this.cols = n;
            this.matrix = new int[this.rows,this.cols];

        }

        public Matrix(int n,int m){
            this.rows = n;
            this.cols = m;

            this.matrix = new int[this.rows,this.cols];
        }

        public void Show()
        {
            for (var i = 0; i < this.rows; i++)
            {
                for (var j = 0; j < this.cols; j++) {
                    Console.Write("{0,3}", this.matrix[i, j]);
                }
                Console.WriteLine();
            }                
        }

        public void ReadElements()
        {
           for (var i = 0; i < this.rows; i++)
                for (var j = 0; j < this.cols; j++)
                {
                    Console.Write("element[{0},{1}]=",i,j);
                    this.matrix[i, j] = Convert.ToInt32(Console.ReadLine());
                }            
        }


        // rotate [n,m] 2D array by 90 deg right
        public void Rotate90DegRight()
        {

            // create a mirror of current matrix
            int[,] mirror = this.matrix;

            // create a new matrix
            this.matrix = new int[this.cols, this.rows];

            for (int i = 0; i < this.rows; i++)
            {
                for (int j = 0; j < this.cols; j++)
                {
                    this.matrix[j, this.rows - i - 1] = mirror[i, j];
                }
            }

            // replace cols count with rows count
            int tmp = this.rows;
            this.rows = this.cols;
            this.cols = tmp;           
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Matrix myMatrix = new Matrix(3,4);
            Console.WriteLine("Enter matrix elements:");
            myMatrix.ReadElements();
            Console.WriteLine("Matrix elements are:");
            myMatrix.Show();
            myMatrix.Rotate90DegRight();
            Console.WriteLine("Matrix rotated at 90 deg are:");
            myMatrix.Show();
            Console.ReadLine();
        }
    }
}

परिणाम:

    Enter matrix elements:
    element[0,0]=1
    element[0,1]=2
    element[0,2]=3
    element[0,3]=4
    element[1,0]=5
    element[1,1]=6
    element[1,2]=7
    element[1,3]=8
    element[2,0]=9
    element[2,1]=10
    element[2,2]=11
    element[2,3]=12
    Matrix elements are:
      1  2  3  4
      5  6  7  8
      9 10 11 12
    Matrix rotated at 90 deg are:
      9  5  1
     10  6  2
     11  7  3
     12  8  4

2

पीएचपी:

<?php    
$a = array(array(1,2,3,4),array(5,6,7,8),array(9,0,1,2),array(3,4,5,6));
$b = array(); //result

while(count($a)>0)
{
    $b[count($a[0])-1][] = array_shift($a[0]);
    if (count($a[0])==0)
    {
         array_shift($a);
    }
}

PHP5.6 से, एरे ट्रांसपोज़िशन को स्लीक array_map()कॉल के साथ किया जा सकता है । दूसरे शब्दों में, कॉलम पंक्तियों में परिवर्तित हो जाते हैं।

कोड: ( डेमो )

$array = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 0, 1, 2],
    [3, 4, 5, 6]
];
$transposed = array_map(null, ...$array);

स्थानांतरित $:

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

1

For i:= 0 to X do For j := 0 to X do graphic[j][i] := graphic2[X-i][j]

X उस सरणी का आकार है जिस पर ग्राफिक अंदर है।


1

#transpose रूबी के ऐरे वर्ग की एक मानक विधि है, इस प्रकार:

% irb
irb(main):001:0> m = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 0, 1, 2], [3, 4, 5, 6]]
=> [[1, 2, 3, 4], [5, 6, 7, 8], [9, 0, 1, 2], [3, 4, 5, 6]] 
irb(main):002:0> m.reverse.transpose
=> [[3, 9, 5, 1], [4, 0, 6, 2], [5, 1, 7, 3], [6, 2, 8, 4]]

कार्यान्वयन सी में लिखा एक ^ ^ 2 ट्रांसपोज़िशन फ़ंक्शन है। आप इसे यहां देख सकते हैं: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-transpose पर क्लिक करके " "पारगमन" के बगल में "टॉगल स्रोत"।

मुझे O (n ^ 2) समाधानों से बेहतर याद है, लेकिन केवल विशेष रूप से निर्मित मैट्रिसेस (जैसे विरल मैट्रिसेस) के लिए


1

किसी भी M * N मैट्रिक्स के लिए मैट्रिक्स रोटेशन 90 डिग्री क्लॉकवाइज में C कोड

void rotateInPlace(int * arr[size][size], int row, int column){
    int i, j;
    int temp = row>column?row:column;
    int flipTill = row < column ? row : column;
    for(i=0;i<flipTill;i++){
        for(j=0;j<i;j++){
            swapArrayElements(arr, i, j);
        }
    }

    temp = j+1;

    for(i = row>column?i:0; i<row; i++){
            for(j=row<column?temp:0; j<column; j++){
                swapArrayElements(arr, i, j);
            }
    }

    for(i=0;i<column;i++){
        for(j=0;j<row/2;j++){
            temp = arr[i][j];
            arr[i][j] = arr[i][row-j-1];
            arr[i][row-j-1] = temp;
        }
    }
}

1

यहाँ C में मेरा In प्लेस कार्यान्वयन है

void rotateRight(int matrix[][SIZE], int length) {

    int layer = 0;

    for (int layer = 0; layer < length / 2; ++layer) {

        int first = layer;
        int last = length - 1 - layer;

        for (int i = first; i < last; ++i) {

            int topline = matrix[first][i];
            int rightcol = matrix[i][last];
            int bottomline = matrix[last][length - layer - 1 - i];
            int leftcol = matrix[length - layer - 1 - i][first];

            matrix[first][i] = leftcol;
            matrix[i][last] = topline;
            matrix[last][length - layer - 1 - i] = rightcol;
            matrix[length - layer - 1 - i][first] = bottomline;
        }
    }
}

1

यहाँ मैट्रिक्स ९ ० डी रोटेशन के लिए मेरा प्रयास है जो सी में २ कदम का समाधान है। पहले मैट्रिक्स को जगह में स्थानांतरित करें और फिर कॉल को स्वैप करें।

#define ROWS        5
#define COLS        5

void print_matrix_b(int B[][COLS], int rows, int cols) 
{
    for (int i = 0; i <= rows; i++) {
        for (int j = 0; j <=cols; j++) {
            printf("%d ", B[i][j]);
        }
        printf("\n");
    }
}

void swap_columns(int B[][COLS], int l, int r, int rows)
{
    int tmp;
    for (int i = 0; i <= rows; i++) {
        tmp = B[i][l];
        B[i][l] = B[i][r];
        B[i][r] = tmp;
    }
}


void matrix_2d_rotation(int B[][COLS], int rows, int cols)
{
    int tmp;
    // Transpose the matrix first
    for (int i = 0; i <= rows; i++) {
        for (int j = i; j <=cols; j++) {
            tmp = B[i][j];
            B[i][j] = B[j][i];
            B[j][i] = tmp;
        }
    }
    // Swap the first and last col and continue until
    // the middle.
    for (int i = 0; i < (cols / 2); i++)
        swap_columns(B, i, cols - i, rows);
}



int _tmain(int argc, _TCHAR* argv[])
{
    int B[ROWS][COLS] = { 
                  {1, 2, 3, 4, 5}, 
                      {6, 7, 8, 9, 10},
                          {11, 12, 13, 14, 15},
                          {16, 17, 18, 19, 20},
                          {21, 22, 23, 24, 25}
                        };

    matrix_2d_rotation(B, ROWS - 1, COLS - 1);

    print_matrix_b(B, ROWS - 1, COLS -1);
    return 0;
}

1

@ डागोरीम: ओ, मैन। मैं इस पर एक अच्छा "मैं ऊब रहा हूं, मैं क्या विचार कर सकता हूं" पहेली के रूप में लटका हुआ था। मैं अपने इन-प्लेस ट्रांसपोज़ेशन कोड के साथ आया था, लेकिन यहाँ मिल गया मेरा बहुत कुछ आपके लिए समान ... आह, ठीक है। यहाँ यह रूबी में है।

require 'pp'
n = 10
a = []
n.times { a << (1..n).to_a }

pp a

0.upto(n/2-1) do |i|
  i.upto(n-i-2) do |j|
    tmp             = a[i][j]
    a[i][j]         = a[n-j-1][i]
    a[n-j-1][i]     = a[n-i-1][n-j-1]
    a[n-i-1][n-j-1] = a[j][n-i-1]
    a[j][n-i-1]     = tmp
  end
end

pp a

1
short normal[4][4] = {{8,4,7,5},{3,4,5,7},{9,5,5,6},{3,3,3,3}};

short rotated[4][4];

for (int r = 0; r < 4; ++r)
{
  for (int c = 0; c < 4; ++c)
  {
    rotated[r][c] = normal[c][3-r];
  }
}

सरल सी ++ विधि, एक बड़ी सरणी में एक बड़ी मेमोरी ओवरहेड होगी।


इन सभी उत्तरों के बीच मैंने यह पाया है और इसका परीक्षण किया है जो कि कॉम्पैक्ट है और घूमने के लिए पर्याप्त है
dlewin
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.