From 9f7299e3a008b6774b9c5573feee1198e5792cc1 Mon Sep 17 00:00:00 2001 From: mathusanm6 Date: Sun, 31 Aug 2025 09:37:08 +0200 Subject: [PATCH 1/3] feat: add problem Contains Duplicate with unit testing --- README.md | 5 +- problems/contains_duplicate/config.yml | 17 ++++ .../contains_duplicate/contains_duplicate.cc | 16 ++++ .../contains_duplicate/contains_duplicate.h | 3 + .../contains_duplicate/contains_duplicate.py | 10 +++ .../contains_duplicate_test.cc | 77 +++++++++++++++++++ .../contains_duplicate_test.py | 50 ++++++++++++ 7 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 problems/contains_duplicate/config.yml create mode 100644 problems/contains_duplicate/contains_duplicate.cc create mode 100644 problems/contains_duplicate/contains_duplicate.h create mode 100644 problems/contains_duplicate/contains_duplicate.py create mode 100644 problems/contains_duplicate/contains_duplicate_test.cc create mode 100644 problems/contains_duplicate/contains_duplicate_test.py diff --git a/README.md b/README.md index c7a7e66..c0ce41a 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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 diff --git a/problems/contains_duplicate/config.yml b/problems/contains_duplicate/config.yml new file mode 100644 index 0000000..82812f8 --- /dev/null +++ b/problems/contains_duplicate/config.yml @@ -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: "" diff --git a/problems/contains_duplicate/contains_duplicate.cc b/problems/contains_duplicate/contains_duplicate.cc new file mode 100644 index 0000000..055b524 --- /dev/null +++ b/problems/contains_duplicate/contains_duplicate.cc @@ -0,0 +1,16 @@ +#include "contains_duplicate.h" + +#include +#include + +bool containsDuplicate(std::vector& nums) { + std::unordered_set seen; + seen.reserve(nums.size()); + for (int& num : nums) { + if (auto iter = seen.find(num); iter != seen.end()) { + return true; + } + seen.insert(num); + } + return false; +} diff --git a/problems/contains_duplicate/contains_duplicate.h b/problems/contains_duplicate/contains_duplicate.h new file mode 100644 index 0000000..96a4070 --- /dev/null +++ b/problems/contains_duplicate/contains_duplicate.h @@ -0,0 +1,3 @@ +#include + +bool containsDuplicate(std::vector& nums); \ No newline at end of file diff --git a/problems/contains_duplicate/contains_duplicate.py b/problems/contains_duplicate/contains_duplicate.py new file mode 100644 index 0000000..d2db556 --- /dev/null +++ b/problems/contains_duplicate/contains_duplicate.py @@ -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 diff --git a/problems/contains_duplicate/contains_duplicate_test.cc b/problems/contains_duplicate/contains_duplicate_test.cc new file mode 100644 index 0000000..b0acedf --- /dev/null +++ b/problems/contains_duplicate/contains_duplicate_test.cc @@ -0,0 +1,77 @@ +#include "contains_duplicate.h" + +#include +#include +#include + +struct ContainsDuplicateCase { + std::string test_name; + std::vector nums; + bool expected; +}; + +using ContainsDuplicateTest = ::testing::TestWithParam; + +TEST_P(ContainsDuplicateTest, TestCases) { + const ContainsDuplicateCase &testCase = GetParam(); + std::vector 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 v; + for (int i = 0; i < 100; ++i) v.push_back(i); + return v; + }(), + .expected = false}, + ContainsDuplicateCase{.test_name = "ManyDuplicates", + .nums = + []() { + std::vector v(50, 1); + v.push_back(2); + return v; + }(), + .expected = true}, + ContainsDuplicateCase{.test_name = "LargeArrayOneDuplicate", + .nums = + []() { + std::vector 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 &info) { + return info.param.test_name; + }); \ No newline at end of file diff --git a/problems/contains_duplicate/contains_duplicate_test.py b/problems/contains_duplicate/contains_duplicate_test.py new file mode 100644 index 0000000..783c7bb --- /dev/null +++ b/problems/contains_duplicate/contains_duplicate_test.py @@ -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 From f036dcd2708ead57718b17f186534c0b92274198 Mon Sep 17 00:00:00 2001 From: Mathusan Selvakumar Date: Sun, 31 Aug 2025 09:39:39 +0200 Subject: [PATCH 2/3] Update problems/contains_duplicate/contains_duplicate.cc Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- problems/contains_duplicate/contains_duplicate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/contains_duplicate/contains_duplicate.cc b/problems/contains_duplicate/contains_duplicate.cc index 055b524..f4c038f 100644 --- a/problems/contains_duplicate/contains_duplicate.cc +++ b/problems/contains_duplicate/contains_duplicate.cc @@ -6,7 +6,7 @@ bool containsDuplicate(std::vector& nums) { std::unordered_set seen; seen.reserve(nums.size()); - for (int& num : nums) { + for (const int& num : nums) { if (auto iter = seen.find(num); iter != seen.end()) { return true; } From b0029287144336edf1a29a8756b523cd3913f730 Mon Sep 17 00:00:00 2001 From: mathusanm6 Date: Sun, 31 Aug 2025 10:00:52 +0200 Subject: [PATCH 3/3] fix: lint warning for cpp --- .../contains_duplicate/contains_duplicate_test.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/problems/contains_duplicate/contains_duplicate_test.cc b/problems/contains_duplicate/contains_duplicate_test.cc index b0acedf..2a407d6 100644 --- a/problems/contains_duplicate/contains_duplicate_test.cc +++ b/problems/contains_duplicate/contains_duplicate_test.cc @@ -1,6 +1,7 @@ #include "contains_duplicate.h" #include +#include #include #include @@ -51,7 +52,10 @@ INSTANTIATE_TEST_SUITE_P( .nums = []() { std::vector v; - for (int i = 0; i < 100; ++i) v.push_back(i); + v.reserve(100); + for (int i = 0; i < 100; ++i) { + v.push_back(i); + } return v; }(), .expected = false}, @@ -67,7 +71,10 @@ INSTANTIATE_TEST_SUITE_P( .nums = []() { std::vector v; - for (int i = 0; i < 5000; ++i) v.push_back(i); + v.reserve(5001); + for (int i = 0; i < 5000; ++i) { + v.push_back(i); + } v.push_back(2500); // Introduce a single duplicate return v; }(),