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的额外空间

  • 相关阅读:
    差分放大电路分析及运放单双电源供电对输出的影响
    反相加法器与同相加法器对比分析
    高频变压器绕组绕制方式与漏感大小分析与计算
    高频变压器绕组绕制方式与分布电容大小分析与计算
    反激电路开关管电流尖峰分析
    涡流效应产生原因及分析
    磁路-电路通用变换方法及电路对偶变换
    反激电路RCD缓冲电路参数设计分析
    STM32 CUBE
    TEB 系统综合误差
  • 原文地址:https://www.cnblogs.com/triStoneL/p/1941905.html
Copyright © 2011-2022 走看看