Algorithm 如何找到计算时间小于O(n)的以下类型的集合?

Algorithm 如何找到计算时间小于O(n)的以下类型的集合?,algorithm,math,data-structures,set,time-complexity,Algorithm,Math,Data Structures,Set,Time Complexity,这里显示了5个不同的集合。S1包含1。考虑以下逻辑,从S1计算下一组S2: 假设Sn包含{a1,a2,a3,a4…,an},Sn的中间元素是b 然后集合Sn+1包含元素{b,b+a1,b+a2,…,b+an}。元素总数(n+1)。如果一个集合包含偶数个元素,则中间元素为(n/2+1) 现在,如果n作为输入,那么我们必须显示集合Sn的所有元素。 显然,在O(n)时间内解决这个问题是可能的 我们可以将所有中间元素计算为(2^(n-1)-前一个集合的中间元素+1),其中s1={1}是基本情况。这样,O

这里显示了5个不同的集合。S1包含1。考虑以下逻辑,从S1计算下一组S2:

  • 假设Sn包含{a1,a2,a3,a4…,an},Sn的中间元素是b
  • 然后集合Sn+1包含元素{b,b+a1,b+a2,…,b+an}。元素总数(n+1)。如果一个集合包含偶数个元素,则中间元素为(n/2+1)
  • 现在,如果n作为输入,那么我们必须显示集合Sn的所有元素。 显然,在O(n)时间内解决这个问题是可能的

    我们可以将所有中间元素计算为(2^(n-1)-前一个集合的中间元素+1),其中s1={1}是基本情况。这样,O(n)次我们将得到所有中间元素,直到第(n-1)集。所以,第(n-1)个集合的中间元素是第n个集合的第一个元素。(第(n-1)集合的中间元素+第(n-2)集合的中间元素)是第n集合的中间第二元素。这样我们将得到第n个集合的所有元素。 所以它需要O(n)时间

    下面是我编写的完整java代码:

    public class SpecialSubset {
    private static Scanner inp;
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
    
        int N,fst,mid,con=0;
    
    
        inp = new Scanner(System.in);
        N=inp.nextInt();
        int[] setarr=new int[N];
        int[] midarr=new int[N];
        fst=1;
        mid=1;
        midarr[0]=1;
        for(int i=1;i<N;i++)
        {
            midarr[i]=(int) (Math.pow(2, i)-midarr[i-1]+1);
        }
        setarr[0]=midarr[N-2];
        System.out.print(setarr[0]);
        System.out.print(" ");
        for(int i=1,j=N-3;i<N-1;i++,j--)
        {
            setarr[i]=setarr[i-1]+midarr[j];
            System.out.print(setarr[i]);
            System.out.print(" ");
    
    
        }
        setarr[N-1]=setarr[N-2]+1;
        System.out.print(setarr[N-1]);
    
    
    
    }
    
    公共类特殊子集{
    专用静态扫描仪;
    公共静态void main(字符串[]args){
    //TODO自动生成的方法存根
    int N,fst,mid,con=0;
    inp=新扫描仪(System.in);
    N=inp.nextInt();
    int[]setarr=新的int[N];
    int[]midarr=新int[N];
    fst=1;
    mid=1;
    midarr[0]=1;
    
    对于(int i=1;i而言,集合中的最小数字似乎是

    其他数字是从第一个数字中通过反向重复添加这些数字获得的

    比如说,

    S6 = {11, 17, 20, 22, 23, 24}
            +6  +3  +2  +1  +1
    

    使用在该链接中找到的Narayana-Zidek-Capell序列的循环,我成功地为这个问题生成了一个在
    O(n)
    时间内运行的解决方案。下面是一个Java解决方案。它只适用于
    n集合中最小的数字似乎是

    其他数字是从第一个数字中通过反向重复添加这些数字获得的

    比如说,

    S6 = {11, 17, 20, 22, 23, 24}
            +6  +3  +2  +1  +1
    

    使用在该链接中找到的Narayana-Zidek-Capell序列的重复,我成功地为这个问题生成了一个在
    O(n)中运行的解决方案
    time。这里有一个Java解决方案。它只适用于
    n。@Paul Boddington给出了一个答案,该答案依赖于这些集合的第一个数字的序列,即Narayana Zidek Capell数,并检查了它的一些小值。但是,没有证据证明所给出的猜想。这个答案是对上述问题的补充我不是HTML/CSS/Markdown的大师,所以你必须原谅下标的错误定位(如果有人可以改进的话,那就做我的客人)

    符号: 设aij为第j组中的第i个数字。
    我还将bj定义为
    j-2
    -th集合的第一个数字。这是证明所涉及的序列,-2用于解释Narayana-Zidek-Capell序列中的第一个和第二个
    1

    生成规则: 问题陈述并没有阐明什么是偶数长度集的“中间编号”(实际上是一个列表,但不管怎样),但在这种情况下,它们似乎是指“中间右侧”。下面我将用粗体表示规则编号

  • a11=1
  • a1n=aceil(n+1/2)n-1
  • ain=a1n+ai-1n-1
  • bn=a1n-2
  • 证明: 第一步是通过稍微展开递归并替换
    b
    ,为ain生成一个稍微复杂的公式:

  • [0…i-1]
  • 下,我们考虑两个BN-1的例子,其中代码< n>代码>为奇数,其中代码代码>为偶数。

    偶数情况:
    b2n+2=a12n=
    2=aceil(2n+1/2)2n-1=an+12n-1=
    3=a12n-1+an2n-2=
    2,4=b2n+1+a12n-1=
    5=2*b2n+1

    奇数格:
    b2n+1=a12n-1=
    2=aceil(2n/2)2n-2=an2n-2=
    3=a12n-2+an-12n-3=
    4=2*b2n+(an-12n-3-a12n-2)=
    2=2*b2n+(an-12n-3-an2n-3)=
    5=2*b2n-bn


    这些规则是精确的序列定义,并提供了一种在线性时间内生成
    n
    th集合的方法(与依次生成每个集合时的二次方法相反)@Paul Boddington给出了一个答案,这个答案依赖于这些集合的第一个数字的顺序,即Narayana Zidek Capell数,并检查了它的一些小值。然而,没有给出猜测的证据。这个答案是对上述答案的补充,以使其完整。我不是HTML/CSS/Markdown大师,所以你必须原谅下标的错误定位(如果有人可以改进的话,请随意)

    符号: 设aij为第j组中的第i个数字。
    我还将bj定义为
    j-2
    -th集合的第一个数字。这是证明所涉及的序列,-2用于解释Narayana-Zidek-Capell序列中的第一个和第二个
    1

    生成规则: 问题陈述并没有阐明什么是偶数长度集的“中间编号”(实际上是一个列表,但不管怎样),但在这种情况下,它们似乎是指“中间右侧”。下面我将用粗体表示规则编号

  • a11=1
  • a1n=aceil(n+1/2)n-1
  • ain=a1n+ai-1n-1
  • bn=a1n-2
  • 证明: 第一步是通过稍微展开递归并替换
    b
    ,为ain生成一个稍微复杂的公式:

  • [0…i-1]
  • 下,我们考虑两个BN-1的例子,其中代码< n>代码>为奇数,其中代码代码>为偶数。

    偶数情况:
    b2n+2=a12n=
    2=aceil(2n+1/2)2n-1=an+12n-1=
    3=a12n-1+an2n
    static Set<Integer> set(int n) {
        int[] a = new int[n + 2];
        for (int i = 1; i < n + 2; i++) {
            if (i <= 2)
                a[i] = 1;
            else if (i % 2 == 0)
                a[i] = 2 * a[i - 1];
            else
                a[i] = 2 * a[i - 1] - a[i / 2];
        }
        Set<Integer> set = new HashSet<>();
        int sum = 0;
        for (int i = n + 1; i >= 2; i--) {
            sum += a[i];
            set.add(sum);
        }
        return set;
    }