当前位置: 首页 > 面试题库 >

为什么此O(n ^ 2)代码比O(n)执行得更快?

费锋
2023-03-14
问题内容

我编写了两种方法的代码,以找出LeetCode字符串中的第一个唯一字符。

问题陈述: 给定一个字符串,找到其中的第一个非重复字符并返回其索引。如果不存在,则返回-1。

示例测试用例:

s =“ leetcode”返回0。

s =“ loveleetcode”,返回2。

方法1(O(n))(如果我错了,请纠正我):

class Solution {
    public int firstUniqChar(String s) {

        HashMap<Character,Integer> charHash = new HashMap<>();

        int res = -1;

        for (int i = 0; i < s.length(); i++) {

            Integer count = charHash.get(s.charAt(i));

            if (count == null){
                charHash.put(s.charAt(i),1);
            }
            else {
                charHash.put(s.charAt(i),count + 1);
            }
        }

        for (int i = 0; i < s.length(); i++) {

            if (charHash.get(s.charAt(i)) == 1) {
                res = i;
                break;
            }
        }

        return res;
    }
}

方法2(O(n ^ 2)):

class Solution {
    public int firstUniqChar(String s) {

        char[] a = s.toCharArray();
        int res = -1;

        for(int i=0; i<a.length;i++){
            if(s.indexOf(a[i])==s.lastIndexOf(a[i])) {
                res = i;
                break;
            }
        }
        return res;
    }
}

在方法2中,我认为复杂度应为O(n ^ 2),因为indexOf在此处以O(n * 1)执行。

但是,当我在LeetCode上执行这两个解决方案时,方法2的运行时间为19毫秒,方法1的运行时间为92毫秒。为什么会这样?

我假设LeetCode对最佳,最差和平均情况下的小和大输入值进行测试。

更新:

我知道以下事实:对于某些n <n1,O(n ^ 2算法)的性能更好。在这个问题中,我想了解为什么在这种情况下会发生这种情况。即方法1的哪一部分使其变慢。

LeetCode链接到问题


问题答案:

对于非常短字符串如单角色作成的成本HashMap,重新调整其大小,查找条目,而装箱和拆箱的charCharacter威力遮荫的成本String.indexOf(),这可能是考虑热和JVM无论哪种方式,内联。

另一个原因可能是RAM访问的成本。随着更多的HashMapCharacterInteger参与查找的对象可能有必要对从RAM额外的访问。单次访问时间约为100
ns,这可能会加起来。

看看 Bjarne Stroustrup:为什么要避免使用链表 。本讲座说明了性能与复杂性并不相同,内存访问可能成为算法的杀手er。



 类似资料:
  • 我正在解决以下问题: null 输入:Array arr是一个非空的唯一整数列表,范围在1到1,000,000,000之间,大小N在1到1,000,000之间 输出:一个数组,其中每个索引i包含一个整数,表示ARR[i]的最大相邻子数组数 示例:arr=[3,4,1,6,2]输出=[1,3,1,5,1] 计算从1到N的每个i的g[i]是一种很有希望的方法,但我们仍然需要考虑如何尽可能有效地这样做。

  • 问题内容: 我刚刚开始学习数据结构,并且在进行数组插入时想知道为什么数组插入的时间复杂度为O(n)而不是O(n + 1)? 在最佳情况下,当插入在最后时,时间复杂度为O(1)。我想我们正在考虑1插入元素,因为这里没有元素被移动。在最坏的情况下,假设我们必须移动n个元素然后插入新元素,那么时间时间复杂度是否应该为O(n + 1)?n用于移动元素,1用于插入。 非常感谢您的帮助。 问题答案: O(n)

  • 问题内容: java.util.Random源代码的第294行说 为什么是这样? 问题答案: 该描述并不完全准确,因为0不是2的幂。更好的说法是 当n是2的幂或2的幂的负数或零时。 如果n是2的幂,则二进制中的n是单个1,后跟零。-n为2的补数是倒数+ 1,因此位排成一行 要了解其工作原理,请将二进制补码视为逆+ 1。 因为当您添加一个得到两个的补码时,您会一直进行到一个。 如果n不是2的幂,则结

  • null 在一个视频教程中,作者提到暴力方法是,阅读另一个答案,一个人认为是,另一个人认为是 强力是还是?更重要的是,您能说明您对蛮力方法执行了哪些分析以知道它是吗?