LeetCode 861 翻轉矩陣後的得分
阿新 • • 發佈:2020-12-12
有一個二維矩陣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。為了做到這一點,我們可以翻轉那些最左邊的數不為1的那些行,而其他的行則保持不動。
當將每一行的最左邊的數都變為 1 之後,就只能進行列翻轉了。為了使得總得分最大,我們要讓每個列中 1的數目儘可能多。因此,我們掃描除了最左邊的列以外的每一列,如果該列 0 的數目多於 1 的數目,就翻轉該列,其他的列則保持不變。
對於最左邊的列而言,由於最優情況下,它們的取值都為1,因此每個元素對分數的貢獻都為,總貢獻是。
對於第j 列(j>0,此處規定最左邊的列是第0列)而言,我們統計這一列0,1 的數量,令其中的最大值為k,則k是列翻轉後的1的數量,該列的總貢獻為需要注意的是,在統計0,1 的數量的時候,要考慮最初進行的行反轉。
注意本題只用返回分數,可以不對矩陣進行操作變換。
public static int matrixScore(int[][] A) { int m = A.length, n = A[0].length; int score = m * (1 << (n-1)); for (int j = 1; j < n; j++) { int one_nums = 0; for (int i = 0; i < m; i++) { if(A[i][0] == 1) { one_nums += A[i][j]; } else if (A[i][0] == 0) { // 如果這一行進行了行反轉,則該元素的實際取值為 1 - A[i][j] one_nums += 1 - A[i][j]; } } int k = Math.max(one_nums, m-one_nums); score += k * (1 << (n-j-1)); } return score; }