LeetCode0861.翻轉矩陣後的得分
阿新 • • 發佈:2018-11-20
861.翻轉矩陣後的得分
描述
有一個二維矩陣 A
其中每個元素的值為 0
或 1
。
移動是指選擇任一行或列,並轉換該行或列中的每一個值:將所有 0
都更改為 1
,將所有 1
都更改為 0
。
在做出任意次數的移動後,將該矩陣的每一行都按照二進位制數來解釋,矩陣的得分就是這些數字的總和。
返回儘可能高的分數。
例項\
輸入:[[0,0,1,1],[1,0,1,0],[1,1,0,0]]
輸出:39
解釋:
轉換為 [[1,1,1,1],[1,0,0,1],[1,1,1,1]]
0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
提示
1 <= A.length <= 20
1 <= A[0].length <= 20
A[i][j]
是0
或1
題解
一個矩陣計算每一行的二進位制之和,也就是每一列中權重都是相同的,那麼只要儘可能讓每一排的第一個元素是1
並且每一列中的1
儘可能多
- 檢查每一行的開頭,如果值為
0
就將這一行翻轉 - 檢查每一列中
1
和0
的個數,如果0
多就將這一列翻轉
public static int matrixScore(int[][] A) {
int h = A.length;
int w = A[0].length;
int[] shuiPing = new int[h] ;//記錄每一列中1的個數
int[] chuiZhi = new int[w];//記錄每一排中1的個數
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
shuiPing[i] += A[i][j];
chuiZhi[j] += A[i][j];
}
}
boolean isChange = true;
while (isChange){
isChange = false;
for (int i = 0; i < w; i++) {
if (h-chuiZhi[i] > chuiZhi[i]){
for (int j = 0; j < h; j++) {
if ((A[j][i] == 1)) {
A[j][i] = 0;
shuiPing[j]--;
chuiZhi[i]--;
} else {
A[j][i] = 1;
shuiPing[j]++;
chuiZhi[i]++;
}
}
isChange = true;
}
}
for (int i = 0; i < h; i++) {
if (A[i][0] == 0){
for (int j = 0; j < w; j++) {
if ((A[i][j] == 1)) {
A[i][j] = 0;
shuiPing[i]--;
chuiZhi[j]--;
} else {
A[i][j] = 1;
shuiPing[i]++;
chuiZhi[j]++;
}
}
isChange = true;
}
}
}
int sum = 0;
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
sum += A[i][j] * Math.pow(2,w-j-1);
}
}
return sum;
}
檢視範例程式碼看到一個更加精簡的.
- 每一行的第一個元素都可以通過對列翻轉將其變成
1
- 完成了上一步之後,每一列中
1
的數量可以通過翻轉變成這一列中Math.max(num(0),num(1))
public int matrixScore(int[][] A) {
int m = A.length;
int n = A[0].length;
int sum = 0;
for(int i = 0; i < m; i++) {
if(A[i][0] == 0) {
for(int j = 0; j < n; j++) {
A[i][j] = 1 - A[i][j];
}
}
}
sum += m * (int)Math.pow(2, n - 1);
for(int j = 1; j < n; j++) {
int count = 0;
for(int i = 0; i < m; i++) {
if(A[i][j] == 1) {
count ++;
}
}
if(2 * count < m) {
count = m - count;
}
sum += count * (int)Math.pow(2, n - j - 1);
}
return sum;
}