【问题标题】:how to find a specific column in 2d array using divide and conquer如何使用分治法在二维数组中查找特定列
【发布时间】:2020-02-27 05:29:57
【问题描述】:

我正在尝试解决一个分而治之的问题,其中我有一个充满真假的二维布尔数组。我试图找到一个特定的列,它是唯一的。还有另一种查找此列的方法是查找仅包含 1 个真索引而其余为假的行。我必须找到小于 O(N^2) 的解决方案

二维数组样本:

F F T F
F T T T
F F T T
T F T F

【问题讨论】:

  • 我认为这是不可能的,除非数组有一些额外的约束。如果您是自己构建数组,那么您可能已经得到了答案。
  • 有一个约束,如果我在数组中找到只有 1 个 true 元素的行,那么这个 1 true 的索引将与所有 true 的库相同。
  • 我明白了,那么它可能在 O(n) 内完成。
  • 发布了 O(n) 解决方案并投票赞成这个问题,这是一个很好的练习。
  • 执行此操作的一种方法:选择任意行作为驾驶行。它显然会有正确的列。扫描此行以查找已设置的元素 ('T')。当您找到一个时,然后上下扫描该列以查找“F”。如果找到一个,则中止该列。否则,您已找到正确的列(结束)。 :) 继续扫描“驱动行”,重复扫描,直到找到正确的列。我怀疑它通常会很快。最坏的情况是可怕的。 ;-/

标签: arrays algorithm divide-and-conquer


【解决方案1】:

这是一个 O(n) 解决方案,如果我们知道至少一行只包含一个真值,因此这是我们正在寻找的列。

  1. 将每个列索引添加到哈希集
  2. 对于每一行,使用迭代器遍历集合并执行以下操作:
    1. 如果您遇到该列索引的错误值,请将其从集合中删除。
    2. 如果遇到真值,请将布尔值设置为 true,这样您就知道这是第一次遇到真值,如果已经遇到真值,则继续下一行

集合中剩余的单个值就是解。

这是 O(n),因为 1. 是 O(n) 而 2. 也是 O(n),所以总体来说是 O(n) + O(n) = O(n)。 2. 是 O(n),因为对于每一行,您最多查看 2 个真值(2 是常数),如果遇到假值,则不会再查看该列。

我现在意识到链表比散列集更适合这个任务。实现可能如下所示(出于教育目的,我自己实现了该列表):

public class Node {
    public int value;
    public Node next;
    public Node(int value, Node prev) {
        this.value = value;
        if (prev != null)
            prev.next = this;
    }
}
public int getTrueColumn(boolean[][] array) {
    Node head = new Node(0, null);
    Node current = head;
    for (int i = 1; i < array[0].length; i++)
        current = new Node(i, current);
    for (int i = 0; i < array.length; i++) {
        boolean encounteredTrue = false;
        current = head;
        Node prev = null;
        while (current != null) {
            if (array[i][current.value]) {
                if (encounteredTrue)
                    break;
                encounteredTrue = true;
                prev = current;
            } else {
                if (prev == null)
                    head = current.next;
                else
                    prev.next = current.next;
            }
            current = current.next;
        }
    }
    return head.value;   
}

【讨论】:

  • 我个人更喜欢在发布之前测试我的代码!
  • @RoxcH 你不能使用随机发生器。必须满足两个条件:1. 必须有一列所有值都为真, 2. 必须有一行除一个之外的所有值都为假。这在问题中有所说明。
  • 好吧,我必须承认我忽略了那个奇怪的约束……我会收回我的帖子!
猜你喜欢
  • 1970-01-01
  • 2021-08-22
  • 1970-01-01
  • 2013-10-25
  • 2023-01-24
  • 2021-09-23
  • 2016-12-25
  • 1970-01-01
  • 2013-05-29
相关资源
最近更新 更多