Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
### 📊 Repository Stats

[![Last Commit](https://img.shields.io/github/last-commit/mathusanm6/LeetCode?style=for-the-badge&logo=git&logoColor=white)](https://github.com/mathusanm6/LeetCode/commits/main)
[![C++ Solutions](https://img.shields.io/badge/C%2B%2B%20Solutions-2-blue?style=for-the-badge&logo=cplusplus&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)
[![Python Solutions](https://img.shields.io/badge/Python%20Solutions-2-green?style=for-the-badge&logo=python&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)
[![C++ Solutions](https://img.shields.io/badge/C%2B%2B%20Solutions-3-blue?style=for-the-badge&logo=cplusplus&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)
[![Python Solutions](https://img.shields.io/badge/Python%20Solutions-3-green?style=for-the-badge&logo=python&logoColor=white)](https://github.com/mathusanm6/LeetCode/tree/main/problems)

</div>

Expand Down Expand Up @@ -104,6 +104,7 @@ make lint-python # Lint Python files with ruff
| # | Title | Solution | Time | Space | Difficulty | Tag | Note |
|---|-------|----------|------|-------|------------|-----|------|
| 1 | [Two Sum](https://leetcode.com/problems/two-sum/) | [Python](./problems/two_sum/two_sum.py), [C++](./problems/two_sum/two_sum.cc) | _O(n)_ | _O(n)_ | Easy | | |
| 217 | [Contains Duplicate](https://leetcode.com/problems/contains-duplicate/description/) | [Python](./problems/contains_duplicate/contains_duplicate.py), [C++](./problems/contains_duplicate/contains_duplicate.cc) | _O(n)_ | _O(n)_ | Easy | | |

## Two Pointers

Expand Down
17 changes: 17 additions & 0 deletions problems/contains_duplicate/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
problem:
number: 217
title: "Contains Duplicate"
leetcode_url: "https://leetcode.com/problems/contains-duplicate/description/"
difficulty: "easy"
tags: ["Arrays & Hashing"]

solutions:
python: "problems/contains_duplicate/contains_duplicate.py"
cpp: "problems/contains_duplicate/contains_duplicate.cc"

complexity:
time: "O(n)"
space: "O(n)"

notes: ""
readme_link: ""
16 changes: 16 additions & 0 deletions problems/contains_duplicate/contains_duplicate.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "contains_duplicate.h"

#include <unordered_set>
#include <vector>

bool containsDuplicate(std::vector<int>& nums) {
std::unordered_set<int> seen;
seen.reserve(nums.size());
for (int& num : nums) {
Comment thread
mathusanm6 marked this conversation as resolved.
Outdated
if (auto iter = seen.find(num); iter != seen.end()) {
return true;
}
seen.insert(num);
}
return false;
}
3 changes: 3 additions & 0 deletions problems/contains_duplicate/contains_duplicate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include <vector>

bool containsDuplicate(std::vector<int>& nums);
10 changes: 10 additions & 0 deletions problems/contains_duplicate/contains_duplicate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from typing import List


def containsDuplicate(nums: List[int]) -> bool:
seen = set()
for num in nums:
if num in seen:
return True
seen.add(num)
return False
77 changes: 77 additions & 0 deletions problems/contains_duplicate/contains_duplicate_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#include "contains_duplicate.h"

#include <gtest/gtest.h>
#include <string>
#include <vector>

struct ContainsDuplicateCase {
std::string test_name;
std::vector<int> nums;
bool expected;
};

using ContainsDuplicateTest = ::testing::TestWithParam<ContainsDuplicateCase>;

TEST_P(ContainsDuplicateTest, TestCases) {
const ContainsDuplicateCase &testCase = GetParam();
std::vector<int> nums = testCase.nums; // Copy since function takes non-const reference
const bool result = containsDuplicate(nums);
EXPECT_EQ(result, testCase.expected);
}

INSTANTIATE_TEST_SUITE_P(
ContainsDuplicateTestCases, ContainsDuplicateTest,
::testing::Values(
// Boundary conditions
ContainsDuplicateCase{.test_name = "EmptyArray", .nums = {}, .expected = false},
ContainsDuplicateCase{.test_name = "SingleElement", .nums = {42}, .expected = false},

// Basic cases
ContainsDuplicateCase{.test_name = "TwoUnique", .nums = {1, 2}, .expected = false},
ContainsDuplicateCase{.test_name = "TwoDuplicate", .nums = {1, 1}, .expected = true},
ContainsDuplicateCase{.test_name = "ThreeUnique", .nums = {1, 2, 3}, .expected = false},
ContainsDuplicateCase{
.test_name = "ThreeWithDuplicate", .nums = {1, 2, 1}, .expected = true},

// Edge cases with special values
ContainsDuplicateCase{.test_name = "ZeroDuplicate", .nums = {0, 1, 0}, .expected = true},
ContainsDuplicateCase{
.test_name = "NegativeDuplicate", .nums = {-1, -2, -1}, .expected = true},
ContainsDuplicateCase{
.test_name = "MinMaxValues", .nums = {INT_MIN, INT_MAX, INT_MIN}, .expected = true},

// Position sensitivity
ContainsDuplicateCase{
.test_name = "DuplicateAtEnd", .nums = {1, 2, 3, 4, 5, 1}, .expected = true},
ContainsDuplicateCase{
.test_name = "DuplicateAtBoundaries", .nums = {5, 1, 2, 3, 4, 5}, .expected = true},

// Performance edge cases
ContainsDuplicateCase{.test_name = "LargeUniqueArray",
.nums =
[]() {
std::vector<int> v;
for (int i = 0; i < 100; ++i) v.push_back(i);
return v;
}(),
.expected = false},
ContainsDuplicateCase{.test_name = "ManyDuplicates",
.nums =
[]() {
std::vector<int> v(50, 1);
v.push_back(2);
return v;
}(),
.expected = true},
ContainsDuplicateCase{.test_name = "LargeArrayOneDuplicate",
.nums =
[]() {
std::vector<int> v;
for (int i = 0; i < 5000; ++i) v.push_back(i);
v.push_back(2500); // Introduce a single duplicate
return v;
}(),
.expected = true}),
[](const ::testing::TestParamInfo<ContainsDuplicateCase> &info) {
return info.param.test_name;
});
50 changes: 50 additions & 0 deletions problems/contains_duplicate/contains_duplicate_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Test cases for the contains_duplicate function."""

import pytest

from contains_duplicate import containsDuplicate


@pytest.mark.parametrize(
"nums, expected",
[
# Boundary conditions
([], False),
([42], False),
# Basic cases
([1, 2], False),
([1, 1], True),
([1, 2, 3], False),
([1, 2, 1], True),
# Edge cases with special values
([0, 1, 0], True),
([-1, -2, -1], True),
([0, -0], True), # 0 and -0 are equal
# Position sensitivity
([1, 2, 3, 4, 5, 1], True), # duplicate at end
([5, 1, 2, 3, 4, 5], True), # duplicate at start/end
# Performance edge cases
(list(range(100)), False), # no duplicates, larger array
([1] * 50 + [2], True), # many duplicates
(list(range(5000)) + [2500], True), # large array with one duplicate
],
ids=[
"empty_array",
"single_element",
"two_unique",
"two_duplicate",
"three_unique",
"three_with_duplicate",
"zero_duplicate",
"negative_duplicate",
"zero_negative_zero",
"duplicate_at_end",
"duplicate_at_boundaries",
"large_unique_array",
"many_duplicates",
"large_array_one_duplicate",
],
)
def test_contains_duplicate(nums, expected):
"""Test containsDuplicate with various input scenarios."""
assert containsDuplicate(nums) == expected