Javascript 这个矩阵挑战有什么想法或解决方案吗?

Javascript 这个矩阵挑战有什么想法或解决方案吗?,javascript,algorithm,recursion,Javascript,Algorithm,Recursion,大家好,我是算法新手,我只是想知道如何解决这个螺旋矩阵挑战: 让函数MatrixSpiral(strArr)读取存储在strArr中的字符串数组,该数组将表示2D N矩阵,程序应在按顺时针螺旋顺序打印元素后返回这些元素。您应该以字符串的形式返回新形成的元素列表,数字之间用逗号分隔。例如:输入: 输出: "4,5,6,5,2,9,2,4,5,1,1,2" 我以前做过简单的矩阵螺旋,但不知道如何解决这样的问题 这不是一个简单的矩阵螺旋。我试过使用这段代码,但输出是完全不同的 输入是一个由“字符串数

大家好,我是算法新手,我只是想知道如何解决这个螺旋矩阵挑战:

让函数MatrixSpiral(strArr)读取存储在strArr中的字符串数组,该数组将表示2D N矩阵,程序应在按顺时针螺旋顺序打印元素后返回这些元素。您应该以字符串的形式返回新形成的元素列表,数字之间用逗号分隔。例如:输入:

输出:

"4,5,6,5,2,9,2,4,5,1,1,2"
我以前做过简单的矩阵螺旋,但不知道如何解决这样的问题

这不是一个简单的矩阵螺旋。我试过使用这段代码,但输出是完全不同的

输入是一个由“字符串数组”组成的数组(请参见双引号),输出应该是一个由逗号分隔的数字组成的字符串。

const spiralOrder = (matrix) => {

if(!matrix.length || !matrix[0].length){
        return [];
}
//Use 4 pointes to create wall around square
let rowBegin = 0,
    rowEnd = matrix.length - 1,
    colBegin = 0,
    colEnd = matrix[0].length - 1;

let result = [];
while(rowBegin <= rowEnd && colBegin <= colEnd){

    //move right
    for(let i= colBegin; i<= colEnd; i++){
            result.push(matrix[rowBegin][i]);
    }
    rowBegin++; // mark row as traversed after moving right

    //move down
    for(let i=rowBegin; i<= rowEnd; i++){
            result.push(matrix[i][colEnd]);
    }
    colEnd--; //mark column as traversed after moving down

    //move left
    if(rowBegin <= rowEnd){
            for(let i=colEnd; i >= colBegin; i--){
                    result.push(matrix[rowEnd][i]); 
            }
    }
    rowEnd--; //mark end row as traversed after moving left

    //move up
    if(colBegin <= colEnd){ 
            for(let i=rowEnd; i >= rowBegin; i--){
                    result.push(matrix[i][colBegin]);
            }
    }
    colBegin++; //mark begining column as traversed after moving up
}

return result;
};

spiralOrder([[4, 5, 6, 5], [1, 1, 2, 2], [5, 4, 2, 9]])

Output: [ '[',
  '4',
  ',',
  ' ',
  '5',
  ',',
  ' ',
  '6',
  ',',
  ' ',
  '5',
  ']',
  ']',
  ']',
  '9',
  ' ',
  ',',
  '2',
  ' ',
  ',',
  '4',
  ' ',
  ',',
  '5',
  '[',
  '[',
  '1',
  ',',
  ' ',
  '1',
  ',',
  ' ',
  '2',
  ',',
  ' ',
  '2' ]
const spiralOrder=(矩阵)=>{
如果(!matrix.length | |!matrix[0].length){
返回[];
}
//使用4个点围绕正方形创建墙
让rowBegin=0,
rowEnd=matrix.length-1,
colBegin=0,
colEnd=矩阵[0]。长度-1;
让结果=[];

而(rowBegin您可以采用四个方向和一个索引对(
i
/
j
)的方法,以及另外四个变量,用于限制具有
上限
下限的循环,以及
左侧
右侧
限制

接受限制后,将递增或递减检查限制。如果限制不在所需范围内,则循环结束

最后,将剩余项添加到结果集中

函数getSpiral(数据){ var array=data.map(j=>JSON.parse(j)), 上限=0, 下限=数组长度-1, 左=0, 右=数组[0]。长度-1, i=上, j=左, 结果=[]; while(true){ 如果(上+++>下)中断; 对于(;j左;j--)result.push(数组[i][j]); 如果(左+++>右)中断; 对于(;i>upper;i--)result.push(数组[i][j]); } 结果:push(数组[i][j]); 返回结果。join(','); } log(getSpiral(['[4,5,6,5]','[1,1,2,2]','[5,4,2,9]]);
log(getSpiral(['[1,2,3,4,5]'、'[6,7,8,9,10]'、'[11,12,13,14,15]'、'[16,17,18,19,20]]);
我们可以观察到旋转(或多或少:)发生在对角线上。函数
f
是主要的递归处理程序,基本上是for循环

功能转弯和三角洲(方向){
返回{
//dy-dx
'r':['d',0,1],
“d”:[l',1,0],
“l”:[u',0,-1],
'u':['r',-1,0]
}[指示]
}
函数是对角的(h,w,y,x){
如果(x>=w>>1)
返回(y==w-x-1)| |(h-y-1==w-x-1)
否则,如果(y>h>>1)
返回(h-y-1==x)
其他的
返回值(y-1==x)
}
函数f(h,w,d,y,x,count,fun){
如果(计数=0)
返回
乐趣(y,x)
设[_d,dy,dx]=TurnandDelta(d)
if(对角线(h,w,y,x))
[\uDy,dx]=TurnandDelta(d=\uD)
f(h,w,d,y+dy,x+dx,计数1,乐趣)
}
功能g(h、w、fun){
f(h,w,'r',0,0,h*w,乐趣)
}
var m=[“[1,2,3,4]”,
"[10,11,12, 5]",
"[ 9, 8, 7, 6]"]
var M=M.map(x=>eval(x))
功能乐趣(y,x){
console.log(M[y][x])
}
g(M.length,M[0]。length,fun)
m=[“[1,2,3]”,
"[10,11, 4]",
"[ 9,12, 5]",
"[ 8, 7, 6]"]
M=M.map(x=>eval(x))

g(M.length,M[0].length,fun)
一种稍微不同的方法,一种适合“递归”标记的方法,是注意处理螺旋线的一个好方法是取顶行,移除它,逆时针旋转矩阵,然后重复,直到完成所有行。它看起来像这样:

->  4 5 6 5  --------------+ 
    1 1 2 2  \_ rotate     |
    5 4 2 9  /          ___V___
                       [4 5 6 5]
                        -------

->  2 9  ------------------------+         
    2 2 \                        |
    1 4  +- rotate               |
    1 5 /                       _V_
                       [4 5 6 5 2 9]
                                ---

->  2 4 5  ---------------------------+  
    2 1 1  >- rotate                __V__
                       [4 5 6 5 2 9 2 4 5]  
                                    -----

->  1  -----------------------------------+
    1  \_ rotate                          |
    2  /                                  V
                       [4 5 6 5 2 9 2 4 5 1]  
                                          - 

->  1 2  ------------------------------------+
                                            _V_
                       [4 5 6 5 2 9 2 4 5 1 1 2]  
                                            ---
我们可以写一个逆时针旋转函数,只需反转矩阵的换位结果。换位就是将其翻转到西北/东南对角线上。例如:

转置([[1,2,3],
[4, 5, 6]])
//=>      [[1, 4],
//         [2, 5],
//         [3, 6]]
反转
那些行,我们得到

/[[3,6],
//         [2, 5],
//         [1, 4]]
这是输入的逆时针旋转

因此,包含一些可重用函数的代码可能如下所示:

->  4 5 6 5  --------------+ 
    1 1 2 2  \_ rotate     |
    5 4 2 9  /          ___V___
                       [4 5 6 5]
                        -------

->  2 9  ------------------------+         
    2 2 \                        |
    1 4  +- rotate               |
    1 5 /                       _V_
                       [4 5 6 5 2 9]
                                ---

->  2 4 5  ---------------------------+  
    2 1 1  >- rotate                __V__
                       [4 5 6 5 2 9 2 4 5]  
                                    -----

->  1  -----------------------------------+
    1  \_ rotate                          |
    2  /                                  V
                       [4 5 6 5 2 9 2 4 5 1]  
                                          - 

->  1 2  ------------------------------------+
                                            _V_
                       [4 5 6 5 2 9 2 4 5 1 1 2]  
                                            ---
const reverse=a=>
[…a].反向();
常量转置=m=>
m[0].map((c,i)=>m.map(r=>r[i]))
常数旋转=m=>
反向(转置(m))
常数螺旋=m=>m.长度<2
?[…m[0]]
:[…m[0],…螺旋(旋转(m.切片(1)))]
常数顺序=(strs)=>
spiral(strs.map(row=>JSON.parse(row)).join(“,”)
控制台日志(
螺旋顺序([“[4,5,6,5]”,
"[1, 1, 2, 2]",  
"[5, 4, 2, 9]"
])

)
可能重复@JohnColeman谢谢你的回答。我已经编辑了我的问题。我认为现在有点不同。谢谢。问题改进了很多。问题的功能解构很好^^