对这个矩阵挑战有任何想法或解决方案吗?

时间:2019-09-15 17:13:43

标签: javascript algorithm recursion

嗨,我是练习算法的新手,我只是想知道如何解决这个螺旋矩阵挑战:

  

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

["[4, 5, 6, 5]",   
 "[1, 1, 2, 2]",  
 "[5, 4, 2, 9]"]   

输出:

"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' ]

可以请您分享任何解决方案吗?

3 个答案:

答案 0 :(得分:3)

您可以采用具有四个方向和一个索引对(from sklearn.model_selection import train_test_split x_in, x_out, y_in, y_out = train_test_split(X, Y, test_size=0.2, stratify=Y) from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.pipeline import Pipeline from sklearn.feature_selection import SelectKBest, chi2, f_classif from sklearn.svm import LinearSVC from sklearn.model_selection import GridSearchCV grid = { 'TF-IDF__ngram_range':[(1,2),(2,3)], 'TF-IDF__stop_words': [None, 'english'], 'SelectKBest__k': [10000, 15000], 'SelectKBest__score_func': [f_classif, chi2], 'linearSVC__penalty': ['l1', 'l2'] } pipeline = Pipeline([('tfidf', TfidfVectorizer(sublinear_tf=True)), ('selectkbest', SelectKBest()), ('linearscv', LinearSVC(max_iter=10000, dual=False))]) grid_search = GridSearchCV(pipeline, param_grid=grid, scoring='accuracy', n_jobs=-1, cv=5) grid_search.fit(X=x_in, y=y_in) / i)的方法,以及另外四个变量来限制j和{{1}的循环},以及upperlower的限制。

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

最后,将剩下的项目添加到结果集中。

left

答案 1 :(得分:2)

另一种略有不同的方法(适合“递归”标签)是要注意的一种处理螺旋的好方法是取顶排,将其取出,逆时针旋转矩阵,然后重复进行直至完成所有行。看起来像这样:

->  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]  
                                            ---

我们可以通过反转矩阵转置的结果来编写逆时针旋转函数。换位将其翻转到西北/东南对角线上。例如:

  transpose([[1, 2, 3], 
             [4, 5, 6]])

  //=>      [[1, 4],
  //         [2, 5],
  //         [3, 6]]

reversing这些行,我们得到

  //        [[3, 6],
  //         [2, 5],
  //         [1, 4]]

这是输入的逆时针旋转。

因此,涉及一些可重用功能的代码可能如下所示:

const reverse = a => 
  [...a] .reverse ();

const transpose = m => 
  m [0] .map ((c, i) => m .map (r => r [i]))

const rotate = m => 
  reverse (transpose (m))

const spiral = m => m .length < 2
  ? [... m [0]]
  : [... m [0], ... spiral (rotate (m .slice (1))) ] 

const spiralOrder = (strs) => 
  spiral (strs .map (row => JSON .parse (row)) ) .join (',')


console .log (
  spiralOrder(["[4, 5, 6, 5]",   
               "[1, 1, 2, 2]",  
               "[5, 4, 2, 9]"
  ])
)

spiralOrder是唯一处理您一些异常输入的函数。 spiraltransposerotatereverse对普通矩阵进行逆运算。 (好吧,它是JS,所以它们可以处理数组数组。)

答案 2 :(得分:0)

我们可以观察到对角线上发生转弯(或多或少:)。函数f是主要的递归处理程序,基本上是for循环。

function turnAndDeltas(direction){
  return {
            // dy dx
    'r': ['d', 0, 1],
    'd': ['l', 1, 0], 
    'l': ['u', 0,-1],
    'u': ['r',-1, 0]
  }[direction]
}

function isDiagonal(h, w, y, x){
  if (x >= w >> 1)
    return (y == w - x - 1) || (h - y - 1 == w - x - 1)
  else if (y > h >> 1)
    return (h - y - 1 == x)
  else
    return (y - 1 == x)
}
 
function f(h, w, d, y, x, count, fun){
  if (count == 0)
    return

  fun(y, x)

  let [_d, dy, dx] = turnAndDeltas(d)

  if (isDiagonal(h, w, y, x))
    [_, dy, dx] = turnAndDeltas(d = _d)

  f(h, w, d, y+dy, x+dx, count-1, fun)
}

function g(h, w, fun){
  f(h, w, 'r', 0, 0, h*w, fun)
}

var m = ["[ 1, 2, 3, 4]",
         "[10,11,12, 5]",
         "[ 9, 8, 7, 6]"]
        
var M = m.map(x => eval(x))

function fun(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)