[LeetCode] 861. Score After Flipping Matrix 翻轉矩陣后的分數



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 0s to 1s, and all 1s to 0s.

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. 1 <= A.length <= 20
  2. 1 <= A[0].length <= 20
  3. A[i][j] is 0 or 1.

這道題給了我們一個只有0和1的二維數組,說是每一行代表一個數字,我們可以任意地翻轉任意行和列,問如何能使得每一行代表的數字之和最大。在博主看來,這道題還是挺有意思的,因為你可以寫的很復雜,但如果思路巧妙的話,也可以寫的很簡潔。當然最暴力的解法就是遍歷所有的組合,對於一個 mxn 大小的矩陣,每一行都可以選擇翻與不翻,同理,每一列也可以選擇翻與不翻,那么總共就有 2^(m+n) 種情況,寫起來比較復雜。

這道題最巧妙的解法是用貪婪算法 Greedy Algorithm 來解的,由於數字是由二進制表示的,那么最高位的權重是要大於其他位總和的,比如 1000 就要大於 0111 的,所以當最高位是0的時候,無論如何都是需要翻轉當前行的,那么對於 mxn 的數組來說,每行的二進制數共有n位,最高位是1的話,就是 1<<(n-1),那么共有m行,所以至少能將 m*(1<<(n-1)) 這么大的值收入囊中,既然最高值一定要是1,那么每一行的翻轉情況就確定了,若還想增大數字之和,就只能看各列是否還能翻轉了,而且是從次高位列開始看,因為最高位列必須保證都是1。由於每一行的翻轉情況已經確定了,那么如何才能確定其他位到底是0還是1呢,這里就有個 trick,此時就要看它跟最高位是否相同了,若相同的話,不管最高位初始時是0還是1,最終都要變成1,那么當前位一定最終也會變成1,而一旦跟最高位相反,那么最后一定會是0。我們翻轉當前列的條件肯定是希望翻轉之后1的個數要更多一些,這樣值才能增加,所以就要統計每列當前的1的個數,若小於0的個數,才進行翻轉,然后乘以該列的值,對於第j列,其值為 1<<(n-1-j),參見代碼如下:


class Solution {
public:
    int matrixScore(vector<vector<int>>& A) {
        int m = A.size(), n = A[0].size(), res = (1 << (n - 1)) * m;
        for (int j = 1; j < n; ++j) {
            int cnt = 0;
            for (int i = 0; i < m; ++i) {
                cnt += (A[i][j] == A[i][0]);
            }
            res += max(cnt, m - cnt) * (1 << (n - 1 - j));
        }
        return res;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/861


參考資料:

https://leetcode.com/problems/score-after-flipping-matrix/

https://leetcode.com/problems/score-after-flipping-matrix/discuss/143722/C%2B%2BJavaPython-Easy-and-Concise


[LeetCode All in One 題目講解匯總(持續更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM