From 4cfcf09449d9e51c0c2274e036d0d28d1c18a32e Mon Sep 17 00:00:00 2001 From: Manish Date: Thu, 23 Feb 2023 01:03:22 +1100 Subject: [PATCH] Design Pattern: 1. Sliding Window | Problem: Longest Substring with 'K' Distinct Characters --- ...t_substring_with_k_distinct_characters.cpp | 77 +++++++++++++++++++ CMakeLists.txt | 2 + 2 files changed, 79 insertions(+) create mode 100644 1_longest_substring_with_k_distinct_characters.cpp diff --git a/1_longest_substring_with_k_distinct_characters.cpp b/1_longest_substring_with_k_distinct_characters.cpp new file mode 100644 index 0000000..15b5351 --- /dev/null +++ b/1_longest_substring_with_k_distinct_characters.cpp @@ -0,0 +1,77 @@ +/*/ problem source: + * https://www.geeksforgeeks.org/find-the-longest-substring-with-k-unique-characters-in-a-given-string/ + */ +#include +#include +#include +#include + +class result { +public: + unsigned long longest_start = 0; + unsigned long longest_end = 0; + bool match_found = false; + bool operator==(const result r) { + return longest_start == r.longest_start && longest_end == r.longest_end && + match_found == r.match_found; + }; +}; + +struct input { + std::string s; + unsigned long k; +}; + +struct test_case { + input i; + result r; +}; + +result find(const std::string &s, const unsigned long k) { + result r; + std::unordered_map char_count; + unsigned long start = 0, end = 0; + for (; end < s.length(); end++) { + char_count[s[end]] += 1; + while (char_count.size() > k) { + char_count[s[start]]--; + if (char_count[s[start]] == 0) { + char_count.erase(s[start]); + } + start++; + } + if (char_count.size() == k && + end - start > r.longest_end - r.longest_start) { + r.longest_start = start, r.longest_end = end; + r.match_found = true; + } + } + + if (r.match_found) { + std::cout << "Longest substring is \"" + << s.substr(r.longest_start, r.longest_end - r.longest_start + 1) + << "\" with length " << r.longest_end - r.longest_start + 1 + << ".\n"; + } else { + std::cout << "Could not find any match, not enough unique characters.\n"; + } + return r; +} + +int main() { + std::vector test_cases = {{{"aabacbebebe", 3}, {4, 10, true}}, + {{"aabbcc", 1}, {0, 1, true}}, + {{"aabbcc", 3}, {0, 5, true}}, + {{"aaabbb", 3}, {0, 0, false}}}; + for (const test_case &t : test_cases) { + if (find(t.i.s, t.i.k) == t.r) { + std::cout << "Test case with string \"" << t.i.s << "\" and k=" << t.i.k + << " passed.\n"; + } else { + std::cout << std::flush; + std::cerr << "TEST CASE WITH STRING \"" << t.i.s << "\" AND k=" << t.i.k + << " FAILED.\n"; + } + } + return 0; +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2074d98..03c52f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,3 +6,5 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -g") + +add_executable(1_longest_substring_with_k_distinct_characters 1_longest_substring_with_k_distinct_characters.cpp) \ No newline at end of file