zoukankan      html  css  js  c++  java
  • 查找数组中丢失的元素

    将0到n这n+1个数中取n个放到一个大小为n的数组里,找到丢弃的那个数

    代码
    int search(int *x, int n)
    {
    int sum = ((1 + n) * n) >> 1;
    for (int i = 0; i < n; ++i)
    {
    sum
    -= x[i];
    }
    return sum;
    }

    //if array is sorted
    int binSearch(int *x, int n)
    {
    int s = 0;
    int e = n;
    int u = 0;
    while (s < e)
    {
    u
    = (s + e) / 2;
    if (x[u] != u)
    {
    e
    = u;
    }
    else
    {
    s
    = u + 1;
    }
    }
    return s;
    }

    前一个算法复杂度是O(n),不过有可能sum过大,会溢出,后一个算法复杂度是O(lbn)

    下面是一个不会溢出的版本,相当于把求和的部分拆散了,这个计算过程中sum的值会保持在0-n之间

    代码
    int search1(int *x, int n)
    {
    int tmp = 1;
    int sum = 0;
    for (int i = 0; i < n; ++i)
    {
    while (sum < x[i])
    {
    sum
    += tmp++;
    }
    sum
    -= x[i];
    }
    if (tmp == n)
    return tmp;
    return sum;
    }

    如果缺失的是k个且k<<n,可以通过解多项式的方法来解出缺失的k个数,如果已排序,可以使用如下复杂度为klbn(?)的算法

    代码
    //x: 存储n+k个连续整数中的n个
    //miss: 返回缺失的k个
    //s: x的起始位置
    //e: x的结束位置
    //sn: n+k个连续整数的第一个
    //en: n+k个连续整数的最后一个
    //missIndex: miss数组的索引
    void binSearch1(int* x, int *miss, int s, int e, int sn, int en, int &missIndex)
    {
    if ((e - s) == (en - sn))
    return;
    if ((e - s) < 2)
    {
    for (; sn < en; ++sn)
    {
    if (x[s] != sn)
    {
    miss[missIndex
    ++] = sn;
    }
    else if (s < e)
    {
    ++s;
    }
    }
    }
    else
    {
    int u = (s + e) / 2;
    binSearch1(x, miss, s, u, sn, x[u], missIndex);
    binSearch1(x, miss, u, e, x[u], en, missIndex);
    }
    }

    如果k比较多,而n的数目不是很大的情况下可以使用如下方法.

    代码
    void search2(int *x, int *miss)
    {
    bitset
    <N + K> bs;
    for (int i = 0; i < N; ++i)
    {
    bs.
    set(x[i]);
    }
    for (int i = 0, j = 0; i < N + K; ++i)
    {
    if (!bs[i])
    {
    miss[j
    ++] = i;
    }
    }
    }

    //if array is sorted
    void search3(int *x, int *miss, int n, int k)
    {
    int u = 0;
    int j = 0;
    for (int i = 0; i < n; ++u)
    {
    if (x[i] != u)
    miss[j
    ++] = u;
    else
    ++i;
    }
    for (;u < n + k; ++u)
    {
    miss[j
    ++] = u;
    }
    }

    两个的算法复杂度都是O(n+k),不过前者要多扫一次数组,还要一个bitset的额外空间

  • 相关阅读:
    复利计算单元测试-软件工程
    实验一 操作系统
    <构建之法>前三章读后感—软件工程
    复利计算总结-软件工程
    实验0-操作系统
    复利计算1.0~2.0~3.0~4.0-软件工程(网页版)
    典型用户与场景
    0608场景(用户故事) 任务
    构建之法读后感+学习和诚信
    0603团队变化+sprint第二个冲刺
  • 原文地址:https://www.cnblogs.com/triStoneL/p/1941905.html
Copyright © 2011-2022 走看看