thảo luận Leetcode mỗi ngày

Python:
class Solution:
    def matrixScore(self, grid: List[List[int]]) -> int:
        m = len(grid)
        n = len(grid[0])
        countOnes = [0]*n
        for i in range(m):
            flip = grid[i][0] == 0
            for j in range(n):
                value = grid[i][j]
                if flip:
                    value ^= 1

                if value == 1:
                    countOnes[j] += 1
       
        score = 0
        for i in range(n):
            maxOnes = max(countOnes[i], m - countOnes[i])
            score += maxOnes*(1 << n - i - 1)

        return score

Python:
class Solution:
    def matrixScore(self, grid: List[List[int]]) -> int:
        m = len(grid)
        n = len(grid[0])
        score = m*(1 << n - 1)
        for j in range(1, n):
            countOnes = 0
            for i in range(m):
                value = grid[i][j]
                if grid[i][0] == 0:
                    value ^= 1

                if value == 1:
                    countOnes += 1

            countOnes = max(m - countOnes, countOnes)
            score += countOnes*(1 << (n - j - 1))

        return score
 
Last edited:
Java:
class Solution {
    public int matrixScore(int[][] grid) {
        int rows = grid.length;
        int cols = grid[0].length;
        int res =0;
        // 1000>0111
        for(int i =0;i<rows;i++){
            if(grid[i][0]== 0 ) flip(grid,i,-1);
        }
        
        for(int j=1;j<cols;j++){
            int countZero=0;
            for(int i =0;i<rows;i++){
                if(grid[i][j]==0) countZero++;
            }
            if(countZero*2>rows) flip(grid,-1,j);
        }
        for(int i =0 ; i<rows;i++ ){
            for(int j=0;j<cols;j++){
                res += grid[i][j]<<(cols-1-j);
            }
        }
        return res;
    }
    private void flip(int[][] grid, int row, int col){
        if(row==-1){
            for(int i=0;i<grid.length;i++){
                grid[i][col] = 1-grid[i][col];
            }
        }else{
             for(int j=0;j<grid[0].length;j++){
                grid[row][j] = 1-grid[row][j];
            }
        }
    }
}
 
C++:
  int matrixScore(vector<vector<int>> &grid) {
    int ans = 0;
    int m = grid.size();
    int n = grid[0].size();
    for (int i = 0; i < m; i++) {
      if (grid[i][0] == 0)
        for (int a = 0; a < n; a++) {
          grid[i][a] = abs(grid[i][a] - 1);
        }
    }
    for (int j = 0; j < n; j++) {
      int countZero = 0;
      for (int b = 0; b < m; b++) {
        if (grid[b][j] == 0)
          countZero++;
      }
      if (countZero > m / 2)
        for (int b = 0; b < m; b++) {
          grid[b][j] = abs(grid[b][j] - 1);
        }
    }
    for (int i = 0; i < m; i++) {
      string temp;
      for (int j = 0; j < n; j++) {
        ans += grid[i][j] << (n - j - 1);
      }
    }
    return ans;
  };
 
Tối ưu bằng bitwise sau

Check côt đầu tiên, nếu giá trị đầu tiên bằng 0 => flip hàng tương ứng.
Check các cột tiếp theo. Nếu số lượng 1 < số 0 => flip cột tương ứng.

C++:
    int matrixScore(vector<vector<int>>& grid) {
        int n = grid.size();
        int m = grid[0].size();
        // Step 1
        for(int i = 0 ; i < n; ++i)
          if (grid[i][0] == 0) {   // flip row
            for(int j = 0; j < grid[0].size(); ++j)
              grid[i][j] = (grid[i][j] == 1) ? 0 : 1;
          }
 
        // step 2
        for(int j = 1; j < m; ++j)
          if (count_colums_ones(grid, j) * 2 < n) // flip colms
            for(int i = 0; i < grid.size(); ++i)
              grid[i][j] = (grid[i][j] == 1) ? 0 : 1;
 
        // step 3:
        int ret = 0;
        for(int i = 0; i < n; ++i) ret += val(grid, i);
        return ret;
    }
    int count_colums_ones(vector<vector<int>>& grid, int c) {
      int count = 0;
      for(int j = 0; j < grid.size(); ++j)  count += (grid[j][c] == 1);
      return count;
    }
    int val(vector<vector<int>>& grid, int r) {
      int ret = 0;
      for(auto e: grid[r]) ret = ret*2 + e;
      return ret;
    }
 
Last edited:
C#:
public class Solution
{
    public int MatrixScore(int[][] grid)
    {
        int rows = grid.Length;
        int cols = grid[0].Length;
        int[] nums = new int[rows];

        int[] vertical1BitCount = new int[cols];
        for (int row = 0; row < rows; row++)
        {
            int num = 0;
            bool flip = grid[row][0] == 0;
            for (int col = 0; col < cols; col++)
            {
                num <<= 1;
                int bit = flip ? grid[row][col] ^ 1 : grid[row][col];
                num += bit;
                vertical1BitCount[col] += bit;
            }
            nums[row] = num;
        }

        int mask = 0;
        for (int i = 0; i < vertical1BitCount.Length; i++)
        {
            int oneCount = vertical1BitCount[i];
            if (rows - oneCount < oneCount)
            {
                continue;
            }
            mask |= 1 << cols - i - 1;
        }

        int result = 0;
        for (int i = 0; i < nums.Length; i++)
        {
            result += nums[i] ^ mask;
        }

        return result;
    }
}
 
Ban đầu cứ ngỡ là DP problem, ngồi suy nghĩ cả buổi không ra, cuối cùng mới chuyển hướng sang Greedy

C-like:
class Solution {
    fun matrixScore(grid: Array<IntArray>): Int {
        val rowCount = grid.size
        val columnCount = grid.first().size
        // Greedy rows
        for (i in 0 until rowCount) {
            var rowValue = 0
            var flipRowValue = 0
            for (j in 0 until columnCount) {
                rowValue += grid[i][j] shl (columnCount - 1 - j)
                flipRowValue += (1 - grid[i][j]) shl (columnCount - 1 - j)
            }
            val shouldFlip = rowValue < flipRowValue
            if (shouldFlip) {
                for (j in 0 until columnCount) {
                    grid[i][j] = 1 - grid[i][j]
                }
            }
        }
        // Greedy columns
        for (j in 0 until columnCount) {
            var oneBitCount = 0
            for (i in 0 until rowCount) {
                if (grid[i][j] == 1) oneBitCount++
            }
            val shouldFlip = oneBitCount <= rowCount / 2
            if (shouldFlip) {
                for (i in 0 until rowCount) {
                    grid[i][j] = 1 - grid[i][j]
                }
            }
        }
        // Final result
        var ans = 0
        for (i in 0 until rowCount) {
            var rowValue = 0
            for (j in 0 until columnCount) {
                rowValue += grid[i][j] shl columnCount - 1 - j
            }
            ans += rowValue
        }
        return ans
    }

}
 
Last edited:
1715571681589.png

C#:
public class Solution {
    public static void SwapRow(int[][] grid, int row)
    {
        for(int i =1;i < grid[0].Length;i++)
        {
            if (grid[row][i] == 0) grid[row][i] = 1;
            else
            {
                grid[row][i] = 0;
            }
        }
    }
    public int MatrixScore(int[][] grid)
    {
        double sum = 0;
        int m = grid.Length;
        int n = grid[0].Length;
        for(int i =0;i < m;i++)
        {
            if (grid[i][0] == 0)
            {
                SwapRow(grid,i);
            }
        }
        int[] count1s = new int[n];
        count1s[0] = m;
        sum += Math.Pow(2,n-1) * m;
        for(int i =1;i < n;i++)
        {
            for (int j = 0;j < m;j++)
            {
                if (grid[j][i] == 1)
                {
                    count1s[i]++;
                }
            }
            int c = count1s[i] > m - count1s[i] ? count1s[i] : m - count1s[i];
            sum += Math.Pow(2, n - 1 - i) * c;
        }

        return (int)sum;
    }

}
solution dở hơi cám lợn mà beat cao phết :D
 
có những dạng bài rất wtf :(

Code:
impl Solution {
    pub fn matrix_score(grid: Vec<Vec<i32>>) -> i32 {
        let m = grid.len();
        let n = grid[0].len();

        let hi_mask = !(2u32.pow(n as u32) - 1);

        let mut bitsets = vec![0u32; m];

        for i in 0..m {
            for j in 0..n {
                bitsets[i] |= (grid[i][j] as u32) << (n - j - 1);
            }
        }

        for i in 0..m {
            let negated = !bitsets[i] ^ hi_mask;

            if (negated > bitsets[i]) {
                bitsets[i] = negated;
            }
        }

        for j in 0..(n - 1) {
            let mut count = 0;
            let mask = (1 << j);

            for i in 0..m {
                if (mask & bitsets[i] > 0) {
                    count += 1;
                }
            }

            if (count < m - count) {
                for i in 0..m {
                    bitsets[i] ^= mask;
                }
            }
        }

        bitsets.into_iter().sum::<u32>() as i32
    }
}
 
Bài này proof cũng dễ mà, để tối ưu giá trị mỗi row thì most significant bit luôn phải là bit 1, vì most significant bit phải là 1 thì giá trị số mới max.
Sau đó thì vì mỗi vị trí j ở mỗi column đều mang về 1 giá trị 2^(n-i-1) nên flip làm sao để có nhiều nhất giá trị 1 ở mỗi column nữa là easy :sweat:

via theNEXTvoz for iPhone
 
Bài này proof cũng dễ mà, để tối ưu giá trị mỗi row thì most significant bit luôn phải là bit 1, vì most significant bit phải là 1 thì giá trị số mới max.
Sau đó thì vì mỗi vị trí j ở mỗi column đều mang về 1 giá trị 2^(n-i-1) nên flip làm sao để có nhiều nhất giá trị 1 ở mỗi column nữa là easy :sweat:

via theNEXTvoz for iPhone
vẫn cứ là O(m.n) , ngồi nửa buổi sáng nghĩ cách nhanh hơn nma ko ra thím ạ :(
 
thê bac có vợ chưa :confident:
Hỏi nhiều quá tiếp chiêu đi
fd80e89f23663dc95baacfdb1f9c6bb9.gif

Java:
class Solution {
    public int matrixScore(int[][] grid) {
        int ans = 0;
        for (int i = 0; i < grid.length; i++) {
            ans += checkAndToggleRow(i, grid);
        }
        for (int i = 1; i < grid[0].length; i++) {
            int sumCol = (checkAndToggleCol(i, grid));
            ans += sumCol;
        }
        return ans;
    }
    private int checkAndToggleRow(int row, int[][] grid) {
        if (grid[row][0] == 1) return (int) Math.pow(2, grid[0].length - 1);
        for (int i = 0; i < grid[0].length; i++) {
            grid[row][I] = grid[row][I] == 1 ? 0 : 1;
        }
        return (int) Math.pow(2, grid[0].length - 1);
    }
    private int checkAndToggleCol(int col, int[][] grid) {
        int sum = 0;
        int result = 0;
        for (int i = 0; i < grid.length; i++) {
            sum += grid[I][col];
        }
        sum = Math.max(sum, grid.length - sum);
        result = sum * (int) Math.pow(2, grid[0].length - col - 1);
        return result;
    }
}[/I][/I][/I]
 
Hỏi nhiều quá tiếp chiêu đi View attachment 2490558
Java:
class Solution {
    public int matrixScore(int[][] grid) {
        int ans = 0;
        for (int i = 0; i < grid.length; i++) {
            ans += checkAndToggleRow(i, grid);
        }
        for (int i = 1; i < grid[0].length; i++) {
            int sumCol = (checkAndToggleCol(i, grid));
            ans += sumCol;
        }
        return ans;
    }
    private int checkAndToggleRow(int row, int[][] grid) {
        if (grid[row][0] == 1) return (int) Math.pow(2, grid[0].length - 1);
        for (int i = 0; i < grid[0].length; i++) {
            grid[row][I] = grid[row][I] == 1 ? 0 : 1;
        }
        return (int) Math.pow(2, grid[0].length - 1);
    }
    private int checkAndToggleCol(int col, int[][] grid) {
        int sum = 0;
        int result = 0;
        for (int i = 0; i < grid.length; i++) {
            sum += grid[I][col];
        }
        sum = Math.max(sum, grid.length - sum);
        result = sum * (int) Math.pow(2, grid[0].length - col - 1);
        return result;
    }
}[/I][/I][/I]
Math.pow 2 cringe qué
dv67XHR.jpg

<< n giùm
Q7yXF5l.png
 
Ý tưởng là lặp row trước, làm cột đầu tiên đều là 1 để lấy giá trị lớn nhất.
Sau đó lặp theo cột (từ cột thứ 2) làm cho số lượng số 1 nhiều nhất.

Swift:
class Solution {
    func matrixScore(_ grid: [[Int]]) -> Int {
        func turn(_ item: Int) -> Int {
            if item == 0 {
                return 1
            }
            return 0
        }
       
        var newGrid: [[Int]] = []
        // Cal rows
        for index in 0..<grid.count {
            let row = grid[index]
            if row.first! == 0 {
                var newRow: [Int] = []
                for num in row {
                    newRow.append(turn(num))
                }
                newGrid.append(newRow)
            } else {
                newGrid.append(row)
            }
        }
        // Cal column
        let numColumn = newGrid[0].count
        if numColumn > 1 {
            for x in 1..<numColumn {
                var countOne = 0
                for y in 0..<newGrid.count {
                    countOne += newGrid[y][x]
                }
                if countOne < (newGrid.count - countOne) {
                    for y in 0..<newGrid.count {
                        newGrid[y][x] = turn(newGrid[y][x])
                    }
                }
            }
        }
        // Get results
        var results: Int = 0
        for row in newGrid {
            let binary = row.map(String.init).joined()
            results += Int(binary, radix: 2)!
        }
        return results
    }
}

Update theo gợi ý của bạn bkhoang, tính giá trị luôn đỡ phải loop lại column

Swift:
class Solution {
    func matrixScore(_ grid: [[Int]]) -> Int {

        func turn(_ item: Int) -> Int {
            if item == 0 {
                return 1
            }
            return 0
        }
        
        var newGrid: [[Int]] = []

        // Cal rows
        for index in 0..<grid.count {
            let row = grid[index]
            if row.first! == 0 {
                var newRow: [Int] = []
                for num in row {
                    newRow.append(turn(num))
                }
                newGrid.append(newRow)
            } else {
                newGrid.append(row)
            }
        }

        // Cal column & results
        let numColumn = newGrid[0].count

        var results: Int = newGrid.count * Int(truncating: pow(2, numColumn - 1) as NSDecimalNumber)

        if numColumn > 1 {
            for x in 1..<numColumn {
                var countOne = 0
                for y in 0..<newGrid.count {
                    countOne += newGrid[y][x]
                }
                let maxOne = max(countOne, newGrid.count - countOne)
                results += maxOne * Int(truncating: pow(2, numColumn - x - 1) as NSDecimalNumber)
            }
        }
        return results
    }
}
 
Last edited:
mình thấy nhiều thím làm bài này thì sẽ đi check cột xem có đạt max chưa, nếu chưa thì flip cột, cá nhân mình thấy flip cột ko cần thiết lắm.
Chỉ cấn đếm số 1 trong cột, ktra bằng 1 cái if là đã về max rồi, các thím có thể xem thử cái solution mình post bên trên, đỡ phải loop lại cái cột 1 lần ;D
 
mình thấy nhiều thím làm bài này thì sẽ đi check cột xem có đạt max chưa, nếu chưa thì flip cột, cá nhân mình thấy flip cột ko cần thiết lắm.
Chỉ cấn đếm số 1 trong cột, ktra bằng 1 cái if là đã về max rồi, các thím có thể xem thử cái solution mình post bên trên, đỡ phải loop lại cái cột 1 lần ;D
@LmaoSuVuong nên đọc để đỡ phải flip col ;)
 
Back
Top