给一个矩阵mat,每个格子都是0或1,翻转一个格子会将该格子以及相邻的格子(有共同边)全部翻转(0变为1,1变为0)
求问最少需要翻转几次将所有格子全部置为0。
这题的重点是数据范围,比赛结束看了眼数据范围想把自己锤死= =
m == mat.lengthn == mat[0].length1 <= m <= 31 <= n <= 3-
mat[i][j]is 0 or 1.
也就是。。。。最多也就9个格子。。。。。暴力怎么都能搞出来的。。。。。
首先分析每个格子要么不反转,要么翻转一次,因为翻转2次的效果和不反转是一样的,不需要在考虑两次及以上的情况。
所以问题很简单,DFS 瞎搞搞就好了~~~
/** * @param {number[][]} mat * @return {number} */ /** * 获取一个二维数组的行数和列数 * @param {any[][]} matrix */ const getMatrixRowAndCol = (matrix) => matrix.length === 0 ? [0, 0] : [matrix.length, matrix[0].length]; /** * 翻转矩阵第index个元素 * @param {any [][]} matrix * @param {number} index * @param {any} value */ function flipMatrix(matrix, x, y, r, c) { let dir = [[0,1],[0,-1],[1,0],[-1,0]]; matrix[x][y] = 1 - matrix[x][y]; for (let i = 0; i < 4; i++) { let nx = x + dir[i][0]; let ny = y + dir[i][1]; if (nx < r && nx >= 0 && ny < c && ny >= 0) { matrix[nx][ny] = 1 - matrix[nx][ny]; } } } var minFlips = function(mat) { let [r, c] = getMatrixRowAndCol(mat); const dfs = (i, j, cnt) => { // console.log(i,j,cnt); if (i === r) { if (mat.every(col => col.every(item => !item))) return cnt; return -1; } if (j === c) { return dfs(i+1, 0, cnt); } let result = -1; // not flip (i, j) if ((result = dfs(i, j+1, cnt)) != -1) { return result; } // flip (i, j) flipMatrix(mat, i, j, r, c); if ((result = dfs(i, j+1, cnt+1)) != -1) { return result; } flipMatrix(mat, i, j, r, c); return -1; } return dfs(0, 0, 0); };