diff --git a/others/longest_substring_without_repeating_characters.cpp b/others/longest_substring_without_repeating_characters.cpp new file mode 100644 index 00000000000..3664ad71e7e --- /dev/null +++ b/others/longest_substring_without_repeating_characters.cpp @@ -0,0 +1,110 @@ +/** + * @file + * @brief Solution for Longest Substring Without Repeating Characters problem. + * @details + * Problem link: https://leetcode.com/problems/longest-substring-without-repeating-characters/description/ + * + * Intuition: + * 1) The intuition is straightforward and simple. We track the frequency of characters. + * 2) Since we can't use a string to track the longest substring without repeating characters efficiently (as removing a character from the front of a string isn't O(1)), we optimize the solution using a deque approach. + * + * Approach: + * 1) Initialize an unordered_map to track the frequency of characters. + * 2) Use a deque for pushing characters, and update the result deque (`res`) with the current deque (`temp`) + * whenever we find a longer substring. + * 3) Use a while loop to reduce the frequency from the front, incrementing `i`, + * and removing characters from the `temp` deque as we no longer need them. + * 4) Return `res.size()` as we are interested in the length of the longest substring. + * + * Time Complexity: O(N) + * Space Complexity: O(N) + * + * I hope this helps to understand. + * Thank you! + * @author [Ashish Kumar Sahoo](github.com/ashish5kmax) + **/ + +#include // for IO Operations +#include // for std::unordered_map +#include // for std::deque +#include // for string class/string datatype which is taken as input +#include // for assert + +/** + * @class Longest_Substring + * @brief Class that solves the Longest Substring Without Repeating Characters problem. + */ +class Longest_Substring { +public: + /** + * @brief Function to find the length of the longest substring without repeating characters. + * @param s Input string. + * @return Length of the longest substring. + */ + int lengthOfLongestSubstring(std::string s) { + // If the size of string is 1, then it will be the answer. + if (s.size() == 1) return 1; + + // Map used to store the character frequency. + std::unordered_map m; + int n = s.length(); + + // Deque to remove from back if repeating characters are present. + std::deque temp; + std::deque res; + int i, j; + + // Sliding window approach using two pointers. + for (i = 0, j = 0; i < n && j < n;) { + m[s[j]]++; + + // If repeating character found, update result and remove from the front. + if (m[s[j]] > 1) { + if (temp.size() > res.size()) { + res = temp; + } + + while (m[s[j]] > 1) { + temp.pop_front(); + m[s[i]]--; + i++; + } + } + + // Add the current character to the deque. + temp.push_back(s[j]); + j++; + } + + // Final check to update result. + if (temp.size() > res.size()) { + res = temp; + } + + return res.size(); // Return the length of the longest substring. + } +}; + +/** + * @brief Self-test implementations + * @returns void + */ +static void tests() { + Longest_Substring soln; + assert(soln.lengthOfLongestSubstring("abcabcbb") == 3); + assert(soln.lengthOfLongestSubstring("bbbbb") == 1); + assert(soln.lengthOfLongestSubstring("pwwkew") == 3); + assert(soln.lengthOfLongestSubstring("") == 0); // Test case for empty string + assert(soln.lengthOfLongestSubstring("abcdef") == 6); // Test case for all unique characters + assert(soln.lengthOfLongestSubstring("a") == 1); // Single character + std::cout << "All test cases passed!" << std::endl; +} + +/** + * @brief Main function. + * @return 0 on successful execution. + */ +int main() { + tests(); // run self-test implementations + return 0; +}