輸入給定一個二元的二維矩陣grid
每次可以翻轉一條row,讓每個元素的01反相。
也可以翻轉一條column,讓每個元素的01反相。
可以操作任意多次。
最後把每條row視為一條二進位表達式的數字,並且進行加總,得到最後的分數。
請問分數的最大值是多少?
Example 1:
Input: grid = [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
Output: 39
Explanation: 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
Example 2:
Input: grid = [[0]]
Output: 1
Constraints:
m == grid.length
m代表grid的高度
n == grid[i].length
n代表grid的寬度
1 <= m, n <= 20
高度m和寬度n都介於 1 ~ 20之間。
grid[i][j]
is either 0
or 1
.每個陣列元素都是0或1。
分數是row by row的二進位數字加總。
因此,為了分數最大化,推演出幾個想法。
一.
讓bit 1居首位(MSB)?
因為1XXX ... X > 0XXX ... X
最高位是1永遠會比最高位是0的二進位數字還大,不論後面的分布情況為何。
二.
MSB決定之後,接下來就是讓bit1 盡可能多,為了一致性。
我們採取column wise的掃描方式,從第二高位掃描到最低位。
每個column都採取讓1盡可能多的方式。
如果保持原狀的bit1必較多,就保持原狀。
如果反轉的bit1比較多,就反轉。
class Solution:
def matrixScore(self, grid: List[List[int]]) -> int:
h, w = len(grid), len(grid[0])
# Let MSB of each first column be 1
score = h
# Check from second column to last column
for column in range(1, w):
# Update score in binary representation
score <<= 1
# Option_1
keep = sum( grid[row][column] ^ grid[row][0] for row in range(h) )
# Option_2
flip = h - keep
# Add best score we can get on current column
score += max(keep, flip)
return score
需要一個2D掃描,掃描每個元素恰好一次。
主要計算都是in-place計算,並且所用到的都是固定尺寸O(1)的臨時變數。