You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HashSet初始化时间复杂度及Leetcode元音反转解法性能差异疑问

关于LeetCode「反转字符串中的元音字母」解法性能差异的疑问

我正在解决LeetCode题目「反转字符串中的元音字母」,以下是我的第一种解法:

class Solution {
    public String reverseVowels(String s) {
        String vowels = "aeiouAEIOU";
        char[] arr = s.toCharArray();

        int length = s.length();
        int i = 0;
        int j = length - 1;

        while(i < j && i < length && j > 0) {
            while(i < j && vowels.indexOf(arr[i]) == -1) {
                i ++;
            }
            while(j > i && vowels.indexOf(arr[j]) == -1) {
                j --;
            }
            char temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i ++;
            j --;
        }

        return String.valueOf(arr);
    }
}

由于vowels.indexOf()的时间复杂度为O(n)(n为vowels字符串长度),我决定使用查找更快的数据结构,因此实现了如下HashSet版本:

class Solution {
    public String reverseVowels(String s) {
        Set<Character> set = new HashSet<>(Arrays.asList('A','a','E','e','I','i','O','o','U','u'));
        char[] arr = s.toCharArray();

        int length = s.length();
        int i = 0;
        int j = length - 1;

        while(i < j && i < length && j > 0) {
            while(i < j && !set.contains(arr[i])) {
                i ++;
            }
            while(i < j && !set.contains(arr[j])) {
                j --;
            }
            char temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i ++;
            j --;
        }

        return String.valueOf(arr);
    }
}

我认为用n个字符构造HashSet的时间复杂度为O(n),且每次查找为O(1),本以为该版本会更快,但在LeetCode上,第一种解法耗时3ms,第二种耗时5ms。

请问为何第二种解法更慢?用n个元素构造HashSet的时间复杂度是多少,这在此案例中如何影响运行时?


解答

1. 为何HashSet版本更慢?

  • 极小数据集下线性查找的常数项更低:虽然理论上indexOf是O(k)(k=10,元音数量),但对于只有10个字符的字符串,线性遍历的实际执行速度极快,远低于HashSet查找的开销。HashSet的contains方法需要执行哈希计算、定位桶位置,还要处理潜在的哈希冲突,这些步骤的常数开销远大于遍历10个字符。
  • JVM对字符串方法的高度优化:String.indexOf()是JVM内置的高度优化方法,很多实现是native代码或者经过汇编级优化,执行效率比Java层面的HashSet操作高得多。
  • HashSet的初始化开销:构造HashSet时,需要将10个字符逐个插入,涉及数组初始化、哈希值计算、自动装箱(char转Character对象)等操作。虽然这部分是O(n)复杂度,但对于n=10的场景,初始化的实际耗时在单次测试中占比不可忽略,而第一种解法的元音字符串是常量,初始化几乎没有额外开销。

2. 构造HashSet的时间复杂度及对运行时的影响

构造包含n个元素的HashSet的时间复杂度是O(n),因为每个元素的插入操作平均时间复杂度为O(1)。但在这个案例中:

  • 虽然n=10,O(n)的理论复杂度看起来很低,但实际初始化过程包含多个额外步骤(比如创建HashSet内部数组、处理自动装箱),这些额外的常数开销在单次运行中被放大,导致整体启动成本更高。
  • 加上每次contains调用的常数开销,使得HashSet版本的总耗时超过了直接使用indexOf的版本。

内容的提问来源于stack exchange,提问作者Tea17_Xi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:14:51