【问题标题】:Java in-place algorithm with O(n) time, and extra memory O(1)Java 就地算法,O(n) 时间,额外内存 O(1)
【发布时间】:2013-10-31 17:44:11
【问题描述】:

我在一个网站 (talentbuddy.co) 上发现了这个问题,它混淆了我对 Big-O 表示法的所有了解。

这是问题陈述:

给定一个整数数组,您的任务是将初始数组打印到标准输出 (stdout),但以特殊方式排序:

所有负数都在前,它们在初始数组中的相对位置不变 与正整数相同,但它们排在最后。

预期复杂度:O(N) 时间,额外内存 O(1)

示例输入: -5 2 1 -2 3

示例输出: -5 -2 2 1 3

我知道 O(n) 时间意味着算法运行时间与输入的大小成正比,在这种情况下是数组的大小,但是有额外的内存 O(1) 意味着什么?

是否可以使用单个 for 循环来解决此问题?这是我的解决方案的样子,我不确定它的运行时间是否为 O(n)。

    import java.util.Arrays;
class MyClass {
    public static void relative_sort(Integer[] v) {
        int[] positives = new int[v.length];
        int counter = 0;
        for(int i=0; i < v.length; i++){
            if(v[i] < 0){
                System.out.print(v[i] + " ");   
            }else{
                 positives[counter] = v[i];  
                 counter++;
            }
        }
        for(int i=0; i < counter; i++){
            System.out.print(positives[i] + " ");            
        }
    }
}

非常感谢您的帮助!我真的很感激!

【问题讨论】:

  • 您的额外内存不是O(1),因为positives 的大小是n。如果你有一个额外的静态大小数组(比如 10),它仍然是O(1)
  • 我认为你的运行时间是X,其中O(n) &lt;= X &lt;= 2*O(n),你需要摆脱你的第二个循环......一切都会好起来的......
  • @EugenHalca 2n 仍然是 O(n)
  • 这个问题之前已经出现在 SO 上:stackoverflow.com/questions/4897280/… ... 虽然在坚持数组时,接受的答案使用 O(n^2) 时间。
  • 很确定内存限制将迫使您执行多个循环,以便使用固定大小的临时空间,您可以在其中对输入的部分进行操作,而不是尝试对整个数据集进行操作。

标签: java big-o


【解决方案1】:

您的解决方案是O(n) 时间。在最坏的情况下,您循环遍历数组两次,2n 仍然是O(n)。但是,您的额外内存也是O(n),因为positives 数组的大小为n,不满足O(1) 额外内存的要求。

完全抛弃positives 数组,简单地循环数组两次。第一遍打印底片,第二遍打印正片。这仍然是2n 使其成为O(n) 时间和额外的内存是O(1)

【讨论】:

  • 非常感谢您的解释!现在很有意义:)
【解决方案2】:

额外内存限制意味着您需要使用的任何额外内存必须是一个常数因素。也就是说,它需要x 字节的空间,其中x 是一个不依赖于输入大小的值。

当然,它提到了额外的内存,因为您的数据大小将与其自身成正比,因此它指的是您用于数组本身之外的任何额外(临时?)空间。

在您的解决方案中,您使用的是与输入数据成比例的数组positives。这显然是 O(n) 额外内存,因此不符合您的限制条件。

【讨论】:

    【解决方案3】:

    虽然您可以使用两个循环,但只需摆脱正数组即可。相反,只需使用与第一个循环类似的逻辑

    class MyClass {
    public static void relative_sort(Integer[] v) {
        for(int i=0; i < v.length; i++){
            if(v[i] < 0)
                System.out.print(v[i] + " ");   
        }
        for(int i=0; i < v.length; i++){
            if(v[i] >= 0)
                System.out.print(v[i] + " ");   
        }
    
    }
    }
    

    复杂度是O(N),你甚至不需要额外的常量内存O(1)

    【讨论】:

    • 您忘记删除positives
    • 啊,我不小心,删除了它。谢谢!
    猜你喜欢
    • 2014-04-30
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2018-03-04
    相关资源
    最近更新 更多