查找通过翻转列可以获得的2D数组中具有相同字符的最大行数?

时间:2015-01-26 17:46:45

标签: algorithm dynamic-programming

您将获得一个M X N 2D阵列,该阵列只能包含字符' a'或者' b'。唯一允许的操作是翻转一列,这样每个人都可以进行操作。在该专栏中将成为' b'反之亦然。您可以使用任意数量的列翻转。找到只有' a'的最大行数。或者只是' b'

输入的第一行将给出矩阵尺寸,其余的线将代表矩阵的每一行。

Input:
3 3
a a b
b b b
b b a

Output: 
2

说明: 翻转第3列将使第1行仅包含' a'并且将第2行仅包含' b'。

After flipping column 3:
a a a
b b a
b b b

有人可以提供这个问题的解决方案并解释一下吗?提供代码(最好是Java或Python)也很有帮助。

谢谢!

1 个答案:

答案 0 :(得分:0)

  1. 每列最多翻转一次(因为将其翻转k次相当于将其翻转k mod 2次)。因此,有一组列将被恰好翻转一次。其余的列没有被触及。

  2. 让我们来看一下固定的行。如果我们希望它只有a,我们应该翻转此行中包含b的所有列(反之亦然)。这就是每行为我们提供设置的原因:一组包含a的列和一组包含b的列。显然,它们永远不会相等。

  3. 现在我们可以为每一行生成两个集合并找到最常用的集合。它的出现次数就是答案。

  4. 以下是一个如何以非常简单的方式实现它的想法:我们可以为每一行生成两个字符串,而不是显式生成集合:此行中所有元素的连接结果及其补码(通过补码)我的意思是一个字符串,其中所有a都被b替换,反之亦然。现在我们只需找到最常见的字符串。我们可以使用HashMap来完成。这是我的代码:

    /**
     * Computes the complement of the string.
     */
    private String getComplement(String string) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < string.length(); i++) {
            builder.append(string.charAt(i) == 'a' ? 'b' : 'a');
        }
        return builder.toString();
    }
    
    /**
     * Solves the problem for the matrix.
     */
    public int getMaxRows(String[] matrix) {
        Map<String, Integer> count = new HashMap<>();
        for (String row : matrix) {
            count.put(row, count.getOrDefault(row, 0) + 1);
            String complement = getComplement(row);
            count.put(complement, count.getOrDefault(complement, 0) + 1);
        }
        return Collections.max(count.values());
    }