1. 程式人生 > 其它 >Leetcode: NO.861 翻轉矩陣後的得分

Leetcode: NO.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

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

解題記錄

  • 因為是二進位制,無論行號光看列的話,每一列代表的大小都已相同的,只要最一列1多就好
  • 對於行來看則要求每一行的第一個為1
  • 整體邏輯就是先每行調整為第一個為1,然後每列根據1的個數調整為1的個數大於等於一半即可
/**
 * @author: ffzs
 * @Date: 2020/12/7 上午8:04
 */
public class Solution {
    public int matrixScore(int[][] A) {
        for
(int i = 0; i < A.length; i++) { if (A[i][0] == 0) turnRow(A[i]); } for (int i = 1; i < A[0].length; i++) { turnColumn(A, i); } System.out.println(Arrays.deepToString(A)); int res = 0; for (int[] ints : A) { for (
int i = 0; i < ints.length; i++) { if (ints[i] != 0) res += 1<<(ints.length - i - 1); } } return res; } private void turnRow(int[] row){ for (int i = 0; i < row.length; i++) { if (row[i] == 0) row[i] = 1; else row[i] = 0; } } private void turnColumn(int[][] m, int col) { int count = 0; for (int[] ints : m) { if (ints[col] == 1) count++; } if (count >= m.length-count) return; for (int[] ints : m) { if (ints[col] == 0) ints[col] = 1; else ints[col] = 0; } } }

image-20201207083636672

  • 還可以不更改陣列中的數值,通過直接收集計數
/**
 * @author: ffzs
 * @Date: 2020/12/7 上午8:39
 */
public class Solution2 {
    public int matrixScore(int[][] A) {
        int res = 0;

        for (int i = 0; i < A[0].length; i++) {
            int ones = 0;
            for (int j = 0; j < A.length; j++) {
                if (A[j][0] == 1) ones += A[j][i];
                else ones += (1 - A[j][i]);
            }
            if (ones < A.length - ones) ones = A.length - ones;
            res += ones * (1<<(A[0].length - i - 1));
        }

        return res;
    }
}

image-20201207085352205