如何解决将矩阵沿逆时针方向旋转90度,这是哪里出了问题
给出大小为N x N的方阵mat [] []。任务是在不使用任何额外空间的情况下将其沿逆时针方向旋转90度。 Problem Link
我的逻辑-对于矩阵N x N,通过使用温度变量X-1时间交换从左列->底行->右列->顶行开始的元素,以逆时针方向旋转外窗。外窗的尺寸。我不知道为什么它不起作用。请帮助我找出问题所在。
#include<bits/stdc++.h>
using namespace std;
int main() {
int t=1; cin>>t;
while (t--) {
int n; cin>>n; vector<vector<int>>a(n,vector<int>(n));
for(int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>a[i][j];
for(int k=0;k<n;k++) {
int i=k,j=0,p=n-1-k,q=p-i,temp;
while (q-- && i<p) {
temp=a[i][i];j=i;
while (j<=p) {
swap(temp,a[j][i]);j++;
}j=i+1;
while (j<=p) {
swap(temp,a[p][j]);j++;
}j=p-1;
while (j>=i) {
swap(temp,a[j][p]); j--;
}j=p-1;
while (j>=i) {
swap(temp,a[i][j]); j--;
}
}
}
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) cout<<a[i][j]<<" ";
cout<<"\n";
}
cout<<"\n";
}
}
谢谢
解决方法
[注意:我以前的解决方案使用了额外的内存,而这没有。因此,我已经删除了以前的解决方案,并对其进行了完全更新以提供新的解决方案。]
好吧,如果我们能够使用额外的空间,则可以轻松解决此问题,但事实并非如此。无论如何,它也可以轻松解决,而无需使用其他额外空间。
首先,让我解释一下此问题的解决方案。然后,我将告诉您代码中的错误操作。我的解决方案类似于您的方法。它将输入数组视为环或环的层。见下文:
0 0 0 0 0
0 1 1 1 0
0 1 2 1 0
0 1 1 1 0
0 0 0 0 0
外圈是0,内圈是1,依此类推...
现在,为了论证,让我们假设我们正在使用多余的空间b(尽管我们不会在解决方案中使用此空间)。同样,让我们假设,b是包含旋转矩阵的已求解数组。然后,我们可以说:
b[(n + n - j - 1) % n][i] = a[i][j] // for any i,j
// here "n" is dimension of matrix
// "i",represents ith indexed row of a
// "j",represents jth indexed column of a
// if you having problem,how this thing just dropped from sky,then
// just write down in paper,for some index (x,y) what it becomes when it is rotated
// you'll see some formula like I've described above
好吧,现在,如果您对公式很清楚,请允许我描述一下如何帮助您解决问题:
在上一个圆环图中(我用来显示圆环的那个),您可以看到0的圆环的角元素彼此之间刚刚发生变化,即,当矩阵旋转,它们永远不会干扰其他元素。其他元素也是如此。一个组中始终有四个元素,它们只是彼此交换位置!只有一个例外是中心(如果n为奇数)。而且中心永远不会改变位置...
如果您还观察了四个元素的循环/组,它们只是彼此交换位置,那么我们可以从当前元素的位置找出下一个元素的位置并放置当前元素的值,完成...因此,如何找出下一个位置的值。注意,我们已经讨论过了如何从b
计算a
的结果。因此,我们可以在下面写一些内容:
pair<int,int> getNext(pair<int,int> x,int n) {
return make_pair((n + n - x.second - 1) % n,x.first);
}
现在,要问一下,我们应该关心的是,有(n/2)
个环。因此,我们将转到每个环,遍历每个环的第一行的元素(最后一个环除外,因为它包含在角落中),并运行四个循环以正确替换位置中的值。完整的代码如下:
#include <iostream>
#include <string>
#define N 128
// returns next postition based on present position
// next position means where the present position value should
// be transferred after rotation
pair<int,x.first);
}
int main() {
int a[N][N];
int n;
scanf("%d",&n);
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
scanf("%d",&a[i][j]);
}
}
for(int h = 0; h < (n / 2); h++) {
int s = h;
int e = n - h - 1;
for(int k = s; k < e; k++) {
auto p = make_pair(s,k); // row = s,and col = k
int t = a[p.first][p.second];
for(int c=0; c<4; c++) {
auto p2 = getNext(p,n);
int temp = a[p2.first][p2.second];
a[p2.first][p2.second] = t;
t = temp;
p = p2;
}
}
}
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
printf("%d ",a[i][j]);
}
printf("\n");
}
return 0;
}
现在,您的代码有什么问题:
我想,您已经了解到,您的算法不正确...并且实现方式也有问题...
[P.S。]:请不要只是复制粘贴代码,首先要理解它。另外,以某种方式编写代码,以便他人可以阅读...,如果您发现我提供的算法有任何错误,或者您可能对理解任何概念有疑问,请在评论中让我知道...
,我想提出一种看起来更简单的方法。
让我们假设您有一个char
类型的向量的向量。
a b c d
e f g h
i j k l
m n o p
结果向量必须看起来像
d h l p
c g k o
b f j n
a e i m
可以通过两个步骤构建结果向量。
第一步,交换源向量的行。
m n o p
i j k l
e f g h
a b c d
第二步是相对于对角线对角线交换元素,例如'm'
被'd'
交换,'n'
被'h'
和{{ 1}}与'o'
交换。然后,从向量的末尾开始,对第二行的第二列的元素重复这些操作。
这是一个演示程序。
'l'
程序输出为
#include <iostream>
#include <utility>
#include <vector>
int main()
{
std::vector<std::vector<char>> a =
{
{ 'a','b','c','d' },{ 'e','f','g','h' },{ 'i','j','k','l' },{ 'm','n','o','p' },};
auto n = a.size();
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
for ( size_t i = 0; i < n / 2; i++ )
{
std::swap( a[i],a[n-i-1] );
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
for ( size_t i = 0; i + 1 < n; i++ )
{
for ( size_t j = 0; j + i + 1 < n; j++ )
{
std::swap( a[i][j],a[n-j -1][n - i -1]);
}
}
for ( const auto &row : a )
{
for ( const auto &item : row )
{
std::cout << item << ' ';
}
std::cout << '\n';
}
std::cout << '\n';
return 0;
}