【问题标题】:What will be the optimal solution? [closed]最佳解决方案是什么? [关闭]
【发布时间】:2012-12-07 17:54:27
【问题描述】:

给定n>=0,创建一个模式为{1,1, 2,1, 2, 3, ... 1, 2, 3 .. n}的数组。

例如,如果您给出n=3,您的方法应该返回数组为{1,1,2,1,2,3}

我的解决方案在这里....

public int[] upSeries(int n) {

    int var1 = n + 1;        
    int var2 = n;
    int var3 = (var1*var2) / 2;
    int arr_length = var3;
    int value = 1;
    int index = 0;
    int[] arr = new int[arr_length];
    for (int j = 0; j < arr.length; j++) {
        for (int p = 0; p < j + 1; p++) {
            arr[index] = value;
            value++;

            if (index == arr.length - 1) {
                arr[index] = n;
                break;
            } else {
                index++;
            }
        }
        value = 1;
    }
    return arr;
}

最好的解决方案是什么?

【问题讨论】:

  • 您的解决方案不起作用吗?如果是这样,请告诉我们什么不起作用。如果您实际上是在寻求最佳解决方案,那是主观的,并不是本网站的真正意义。
  • 我的代码正在运行,我只是问有没有时间复杂度低的解决方案
  • 您的解决方案通常没问题。它与输出的大小成线性关系。除非您正在寻找一些惰性列表评估 - 除了一些微优化之外,您无法做任何真正的改进。
  • 如果您的解决方案有效,这里不是发布此问题的地方。一个更好的地方是codereview.stackexchange.com
  • @Ruchi。是的,现在很好。

标签: java arrays algorithm


【解决方案1】:

我清理了一下。但它的一般想法是一样的。您有一些可以删除的冗余。

public int[] upSeries(int i) {
    assert i >= 0;        

    int[] array = new int[(i * (i+1)) / 2)];  // Standard Sum
    int seriesnum = 1;
    int seriesmax= 1;
    for (int index=0; index < array.length; index++) {
        array[index] = seriesnum;            

        if (seriesnum++ == seriesmax) {
            seriesnum = 1;
            seriesmax++;
        }
    }

    return array;
}

这个解决方案最好是常数倍数。如果您正在寻找 Big-Oh,它们都是 O(i^2),不可能做得更好。

如果您需要证明为什么无法做得更好。首先证明返回数组的大小为((i) * (i+1)) /2)。然后提出你必须填充数组中的每个位置的论点。如果你做得比 O(i^2) 好,你还没有填满数组中的每个位置。

【讨论】:

  • n==46341 时还有一个奇怪的边缘情况。详情见我的回答。
  • @nikdeapen 你觉得我的方法怎么样。检查我的答案。
【解决方案2】:

由于整数运算,您的代码对于偶数输入失败。

对于@RohitJain 显示的示例,您执行(4+1)/2,这是错误地给您2。一个可能的解决方案是首先乘以i*(i+1),然后再除以2。


关于性能:
与输出相比,您在线性时间运行 - 每个元素进行一次迭代,没有什么可以做的,也许只有一些局部微优化。


编辑:

新代码还有一个问题——n== 46341 时的一个奇怪的边缘情况,数组大小应该是 1073720970,这在理论上是可能的(AFAIK)。
但是,当乘以 46341*46342 时,您会超出范围,这会导致 整数溢出 - 和一个负大小的数组。

这可以通过手动检查这种情况来解决。

【讨论】:

  • @amit.. OP 已编辑该部分。因此,如果您看到任何其他问题,您可以编辑您的答案以考虑任何其他问题。
  • @RohitJain:还有一个奇怪的边缘案例的问题。已编辑。
  • @amit.. 哦!没有想到那个案子。我会为此给你+1。 :)
【解决方案3】:

Ruchi,您的循环需要 O(n^2) 时间 - 更准确地说,它需要 (n)(n+1)/2 时间。但是,由于这也是数组的大小,所以不可能做得更好。

【讨论】:

    【解决方案4】:

    你的 for 循环很好,这种类型的列表的效率是有限的,但你的代码可以清理一下。 var1 有点没用,var2 仅在 i 为奇数时才有用(否则它不准确),var3 绝对没有任何作用。数组的长度将是 1 到 i 或 ∑iint arr_length = i*(i+1)/2 的总和。你甚至可以把这个总和放在你的数组声明中,这样更容易理解。

    【讨论】:

      【解决方案5】:
      List<Integer> myarrayList=new ArrayList<Integer>();
      public void show(int n){
      for(int i=1;i<n+1;i++){
          if(n==1){
              myarrayList.add(n);
              break;
          }
          if(n>1){
              for(int j=1;j<i+1;j++){
                  myarrayList.add(j);
              }
          }
      
      }
      }
      
      public  int[] convertIntegers(List<Integer> integers)
      {
      int[] ret = new int[integers.size()];
      Iterator<Integer> iterator = integers.iterator();
      for (int i = 0; i < ret.length; i++)
      {
          ret[i] = iterator.next().intValue();
      }
      return ret;
      }
      }
      

      首先调用 show 函数,然后调用 convertIntegers

      【讨论】:

        【解决方案6】:

        这个怎么样。

        public static void main(String args[]) {
        
            int n =3;
            StringBuilder sb = new StringBuilder();
            String prei = "";
            for(int i=1;i<n+1;i++){
                prei    =prei + sb.append(i).toString();
            }
        
             char [] myArr = prei.toCharArray();
            }
        }
        

        【讨论】: