What is the time complexity of populating a HashSet with n elements?

I was working on the Leetcode problem “Reverse Vowels of a String.”

Here is my first solution:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>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);
}
}
</code>
<code>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); } } </code>
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);
    }
}

Since vowels.indexOf() has a time complexity of O(n), where n is the length of the vowels string, I decided to use a faster lookup data structure. Therefore, I implemented a HashSet as follows:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>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);
}
}
</code>
<code>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); } } </code>
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);
    }
}

My understanding is that constructing the HashSet with n characters has a time complexity of O(n), and each lookup is O(1). I expected this version to be faster. However, on Leetcode, the first solution finished in 3 ms, while the second one finished in 5 ms.

Why is the second one slower? What is the time complexity of constructing a HashSet with n elements, and how does it affect runtime in this case?

2

Constructing a HashSet does have O(n) performance, but you can’t use the Big O notation to predict the runtime between different algorithms. You can’t even use it to predict the runtime of add() and contain() in HashSet itself. From a benchmark in Baeldung

Benchmark 1000 10,000 100,000
.add() 0.026 0.023 0.024
.remove() 0.009 0.009 0.009
.contains() 0.009 0.009 0.010

Notice how both add() and contains() are O(1) (constant runtime regardless of collection size), but their runtime is different.

For very small input, the constant (not included in the Big O notation) overhead of a more complex algorithm likely exceeds the time saving for each operation. You’ll only notice the difference once you crank the number to millions.

1

The second solution is slower despite using a HashSet for these reasons:

HashSet Overhead: Constructing the HashSet and calculating hash codes introduces extra overhead, even though lookups are O(1).

Small Set Size: The indexOf() in the first solution scans a small, constant set of 10 vowels, which is efficient. The linear search through a short string has minimal overhead.

Cache Efficiency: indexOf() operates on a small contiguous string, making it more cache-friendly than a HashSet, which has more complex memory access patterns.

Constant Factors: The overhead of HashSet operations (hashing, collision handling) can outweigh the benefits for such a small data set.

In summary, while HashSet has better theoretical complexity, the small set size and overhead make indexOf() faster in practice for this problem.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật