题目:
We have a two dimensional matrix A
where each value is 0
or 1
.
A move consists of choosing any row or column, and toggling each value in that row or column: changing all 0
s to 1
s, and all 1
s to 0
s.
After making any number of moves, every row of this matrix is interpreted as a binary number, and the score of the matrix is the sum of these numbers.
Return the highest possible score.
Example 1:
Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]] Output: 39 Explanation: Toggled to [[1,1,1,1],[1,0,0,1],[1,1,1,1]]. 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
Note:
1 <= A.length <= 20
1 <= A[0].length <= 20
A[i][j]
is0
or1
.
解答
解法1:
- 【先考虑列,再考虑行】
- 【列变换】列的变换不会造成数量级的变化(同一列在同一数量级上),所以追求1个数的最大化.即变换数量(0) > 数量(1)的情况。
- 【行变换】每次变化都会造成数量级的变化。所以目标是使第一位为1(量级最大)。
class Solution {
private boolean canStop = false;
public int matrixScore(int[][] A) {
if(A == null){
return 0;
}
int rowLen = A.length;
if(rowLen == 0) return 0;
int colLen = A[0].length;
while(!canStop){
moveCols(A,rowLen,colLen);
moveRows(A,rowLen,colLen);
}
int result = generateNum(A,rowLen,colLen);
return result;
}
private int generateNum(int[][] A,int rowLen,int colLen) {
int result = 0;
for(int row = 0;row < rowLen;row++){
StringBuilder sb = new StringBuilder();
for(int col = 0; col < colLen;col++){
sb.append(A[row][col]);
}
result += Integer.valueOf(sb.toString(),2);
}
return result;
}
//先纵向,后横向。
//纵向: 按照零得个数
//横向:左边0优先于右边。(最右边有一个0则变)
private void moveCols(int[][] A,int rowLen,int colLen) {
canStop = true;
for(int col = 0; col < colLen;col++){
if(isRightCol(col,A)){
changeCol(col,A);
canStop = false;
}
}
}
private void moveRows( int[][] A,int rowLen,int colLen) {
canStop = true;
for(int row = 0;row < rowLen;row++){
if(isRightRow(row,A)){
changeRow(row,A);
canStop = false;
}
}
}
public boolean isRightRow(int row,int[][] A){
return A[row][0] == 0;
}
public void changeRow(int row, int[][] A){
for(int c = 0; c < A[0].length; c++){
if(A[row][c] == 0){
A[row][c] = 1;
}else{
A[row][c] = 0;
}
}
}
public boolean isRightCol(int col,int[][] A){
int zroNum = 0;
for(int r = 0; r < A.length; r++){
if(A[r][col] == 0){
zroNum ++;
}
}
return zroNum > A.length/2;
}
public void changeCol(int col, int[][] A){
for(int r = 0; r < A.length; r++){
if(A[r][col] == 0){
A[r][col] = 1;
}else{
A[r][col] = 0;
}
}
}
}