【问题标题】:find number of 1s in a 0-1 array with all 1s “on the left”?在 0-1 数组中找到所有 1“在左侧”的 1 的数量?
【发布时间】:2013-03-13 16:31:11
【问题描述】:

一个数组由 N 个许多 1 和 0 组成,所有 1 都在任何 0 之前。在数组中查找没有 1。很明显,二分查找是 O(log N)。是否有算法在 O(log(1 的数量)) 时间内做到这一点?

【问题讨论】:

  • 线性搜索将是O(number of 1s + 1)
  • 抱歉错字应该是 O(log(number of 1's))...
  • 而 Aasmund Eldhuset 的回答说明了如何做到这一点。

标签: algorithm math binary-search


【解决方案1】:

您实际上可以在O(lg m) 时间内完成,其中m 是1 的数量。我不会给出整个算法,因为这看起来像家庭作业,但这里有一个提示:尝试“反转”二分搜索,使其扩大而不是缩小搜索区域。

【讨论】:

  • 你确定它会是 O(lg m) 吗?
  • 我认为@SergeyS 是对的:一旦你达到零,你就必须收缩搜索,不是吗?
  • @angelatlarge: 是的,但是在lg m 扩展之后,你最多只能在最右边1 的右边m 位置,所以你只需要lg m 步骤来收缩又回来了。
  • 啊,是的,你是对的,所以最坏的情况是 2lg(m)。谢谢。
  • 好的,我明白了@Aasmund Eldhuset 的观点,我用 2^i 步解析数组,一旦在最后一步击中 0 就进行二进制搜索。但是如果我在触摸任何 0 之前超过了数组的大小怎么办?
【解决方案2】:

如果你只是迭代这个数组,你计算所有的 1,最后找到 0 你做了 N+1 步,所以在我看来它是 O(n+1) 算法。

【讨论】:

  • O(n+1) = O(n)。函数 n 和 n+1 之间没有渐近差异。
【解决方案3】:
class OneZero
{

    public static int binary_search (byte[] array, int start, int end, int value)
    {

        if (end <= start) return -1;

        if (Math.floor((start+end)/2) == value) return Math.floor((start+end)/2);

        return binary_search (array, start, Math.floor((start+end)/2)-1, value);

    }

    public static int nbOfOnes (byte[] array, int value)
    {

        return (binary_search(array, 0, array.length,value)+1);

    }

    public static void main ()
    {

        byte[] arr = { 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 };

        System.out.println(" number of 1s is: "+nbOfOnes(arr,1));

    }

}

【讨论】:

  • 你忘记在 nbOfOnes 函数体中传递 binary_search 函数的最后一个参数(值)...或者我错过了 smt...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
  • 2011-07-20
  • 2016-02-04
  • 2021-08-28
  • 1970-01-01
  • 2015-12-02
  • 1970-01-01
相关资源
最近更新 更多