Address:
Force bucklehttps://leetcode-cn.com/problems/score-after-flipping-matrix/
Title:
There is A two-dimensional matrix , A, where the value of each element is , 0 , or , 1.
Move refers to selecting any row or column and converting each value in the row or column: change all 0 to 1 and all 1 to 0.
After making any number of moves, each row of the matrix is interpreted according to binary numbers, and the score of the matrix is the sum of these numbers.
Returns the highest possible score.
Example:
Input: [[0,0,1,1], [1,0,1,0], [1,1,0,0]] Output: 39 Explanation: Convert to [[1,1,1,1], [1,0,0,1], [1,1,1,1]] 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39 |
Tips:
1 <= A.length <= 20 1 <= A[0].length <= 20 A[i][j] is 0 or 1 |
Source: LeetCode
Link: https://leetcode-cn.com/problems/score-after-flipping-matrix
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.
Idea:
For a binary representation, if you want a large number, the high bit should be equal to 1 as much as possible
For example:
So for a matrix that expresses binary numbers like this
Each line is a binary number. The first goal is to set all the highest bits to 1
Phase I:
So we scan column 0 of each row. If the value is not 0, we flip the row
First line:
Second line:
The third line is not 0. No line transformation is performed
Phase II:
We can't do row transformation anymore. If we do it again, the highest bit may change. At this stage, we deal with column transformation
The starting column starts from the first column and compares the number of 0 elements and 1 elements in this column
Only when the number of 1 element is more, the sum of addition is greater
The first column: all 1, no transformation
The second column: 0:2, 1:1, column transformation
The third column: 0:2, 1:1, column transformation
Phase III:
After the first two stages, we get the final matrix, and the rest is to traverse the matrix rows
Convert binary number to decimal number
For example: 1 0 1
1*2^3 + 1*2^2 + 0*2^1 + 1*2^0
In the implementation part, you need to create two additional two-dimensional arrays
Or the original matrix:
Row array | Number of elements 0 | Number of elements 1 |
countRowArr | [0][0] = 3 | [0][1] = 1 |
[1][0] = 3 | [1][1] = 1 | |
[2][0] = 2 | [2][1] = 2 |
Column array | Number of elements 0 | Number of elements 1 |
countColArr | [0][0] = 2 | [0][1] = 1 |
[1][0] = 2 | [1][1] = 1 | |
[2][0] = 2 | [2][1] = 1 | |
[3][0] = 2 | [3][1] = 1 |
When it is determined that row transformation or column transformation is required, the values of the above two-dimensional arrays shall be updated accordingly
Method 1: dynamically update the value
There are a little more codes. The main logic is as follows:
1. Create two 2D arrays
2. Line transformation
3. Column transformation
4. After the transformation is completed, calculate the binary decimal value
int **countRowArr = createCountGrid(grid, row, col, "row"); int **countColArr = createCountGrid(grid, row, col, "col"); /* reverse */ for(i=0; i<row; i++) { if(grid[i][0] == 0) { doReverse(grid, row, col, i, -1, countRowArr, countColArr, "row"); } } for(i=1; i<col; i++) { if( needReverse(countColArr, i) ) doReverse(grid, row, col, -1, i, countRowArr, countColArr, "col"); } /* caculate */ for(i=0; i<row; i++) { ret += cacul(grid[i], col); }
The rest of the code is to realize the above functions, and the following is the whole code:
int ** createCountGrid(int **grid, int row, int col, char *content) { int i,j; if(strcmp(content, "row") == 0) { /* store numbers of 0 1 in each row */ int **countRowArr = (int **)malloc(sizeof(int *) * row); for(i=0; i<row; i++) { countRowArr[i] = (int *)malloc(sizeof(int) * 2); } /* init countRowArr */ for(i=0; i<row; i++) { int zero = 0, one = 0; for(j=0; j<col; j++) { if(grid[i][j] == 0) zero++; else one++; } countRowArr[i][0] = zero; countRowArr[i][1] = one; } return countRowArr; } else { /* store numbers of 0 1 in each col */ int **countColArr = (int **)malloc(sizeof(int *) * col); for(i=0; i<col; i++) { countColArr[i] = (int *)malloc(sizeof(int) * 2); } /* init countColArr */ for(j=0; j<col; j++) { int zero = 0, one = 0; for(i=0; i<row; i++) { if(grid[i][j] == 0) zero++; else one++; } countColArr[j][0] = zero; countColArr[j][1] = one; } return countColArr; } return NULL; } void freeCountGrid(int **grid, int row, int col, char *content) { int i; int drow, dcol; if(strcmp(content, "row") == 0) drow = row; else drow = col; for(i=0; i<drow; i++) { free(grid[i]); } free(grid); } void dispGrid(int **grid, int row, int col, char *content) { int i, j; int drow, dcol; if(strcmp(content, "row") == 0) { drow = row; dcol = 2; } else if(strcmp(content, "col") == 0) { drow = col; dcol = 2; } else { drow = row; dcol = col; } for(i=0; i<drow; i++) { for(j=0; j<dcol; j++) { printf("disp...%s, grid[%d][%d]=%d\n", content, i, j, grid[i][j]); } } } bool needReverse(int **countArr, int idx) { if(countArr[idx][0] >= countArr[idx][1]) return true; else return false; return false; } void doReverse(int **grid, int row, int col, int revRowIdx, int revColIdx, int **countRowArr, int **countColArr, char *content) { int i; if(strcmp(content, "row") == 0) // reverse row { for(i=0; i<col; i++) { if(grid[revRowIdx][i] == 0) { grid[revRowIdx][i] = 1; countRowArr[revRowIdx][0] --; countRowArr[revRowIdx][1] ++; countColArr[i][0] --; countColArr[i][1] ++; } else { grid[revRowIdx][i] = 0; countRowArr[revRowIdx][0] ++; countRowArr[revRowIdx][1] --; countColArr[i][0] ++; countColArr[i][1] --; } } } else { for(i=0; i<row; i++) { if(grid[i][revColIdx] == 0) { grid[i][revColIdx] = 1; countColArr[revColIdx][0] --; countColArr[revColIdx][1] ++; countRowArr[i][0] --; countRowArr[i][1] ++; } else { grid[i][revColIdx] = 0; countColArr[revColIdx][0] ++; countColArr[revColIdx][1] --; countRowArr[i][0] ++; countRowArr[i][1] --; } } } } int cacul(int *arr, int len) { int num = 0; int k = 0; for(int i=len-1; i>=0; i--) { if(arr[k++] == 0) continue; int j = i; int tmp = 1; while(j) { tmp *= 2; j--; } num += tmp; } return num; } int matrixScore(int** grid, int gridSize, int* gridColSize){ int i, j; int ret = 0; int row = gridSize; int col = gridColSize[0]; int **countRowArr = createCountGrid(grid, row, col, "row"); int **countColArr = createCountGrid(grid, row, col, "col"); // dispGrid(grid, row, col, "all"); // dispGrid(countRowArr, row, col, "row"); // dispGrid(countColArr, row, col, "col"); /* reverse */ for(i=0; i<row; i++) { if(grid[i][0] == 0) { doReverse(grid, row, col, i, -1, countRowArr, countColArr, "row"); } } // dispGrid(grid, row, col, "all"); // dispGrid(countRowArr, row, col, "row"); // dispGrid(countColArr, row, col, "col"); for(i=1; i<col; i++) { if( needReverse(countColArr, i) ) doReverse(grid, row, col, -1, i, countRowArr, countColArr, "col"); } //dispGrid(grid, row, col, "all"); // dispGrid(countRowArr, row, col, "row"); // dispGrid(countColArr, row, col, "col"); /* caculate */ for(i=0; i<row; i++) { ret += cacul(grid[i], col); } /* free */ freeCountGrid(countRowArr, row, col, "row"); freeCountGrid(countColArr, row, col, "col"); return ret; }