Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
realstealthninja authored Oct 20, 2024
2 parents a841b20 + d438f0f commit 3da5e2a
Show file tree
Hide file tree
Showing 5 changed files with 498 additions and 66 deletions.
3 changes: 3 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@
* [Kadanes3](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/others/kadanes3.cpp)
* [Kelvin To Celsius](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/others/kelvin_to_celsius.cpp)
* [Lfu Cache](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/others/lfu_cache.cpp)
* [Longest Substring Without Repeating Characters](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/others/longest_substring_without_repeating_characters.cpp)
* [Lru Cache](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/others/lru_cache.cpp)
* [Matrix Exponentiation](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/others/matrix_exponentiation.cpp)
* [Palindrome Of Number](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/others/palindrome_of_number.cpp)
Expand All @@ -324,6 +325,7 @@
* [Addition Rule](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/probability/addition_rule.cpp)
* [Bayes Theorem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/probability/bayes_theorem.cpp)
* [Binomial Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/probability/binomial_dist.cpp)
* [Exponential Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/probability/exponential_dist.cpp)
* [Geometric Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/probability/geometric_dist.cpp)
* [Poisson Dist](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/probability/poisson_dist.cpp)
* [Windowed Median](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/probability/windowed_median.cpp)
Expand All @@ -338,6 +340,7 @@
* [Sparse Table](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/range_queries/sparse_table.cpp)

## Search
* [Longest Increasing Subsequence Using Binary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/search/Longest_Increasing_Subsequence_using_binary_search.cpp)
* [Binary Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/search/binary_search.cpp)
* [Exponential Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/search/exponential_search.cpp)
* [Fibonacci Search](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/search/fibonacci_search.cpp)
Expand Down
110 changes: 110 additions & 0 deletions others/longest_substring_without_repeating_characters.cpp
Original file line number Diff line number Diff line change
@@ -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 <iostream> // for IO Operations
#include <unordered_map> // for std::unordered_map
#include <deque> // for std::deque
#include <string> // for string class/string datatype which is taken as input
#include <cassert> // 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<char, int> m;
int n = s.length();

// Deque to remove from back if repeating characters are present.
std::deque<char> temp;
std::deque<char> 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;
}
151 changes: 151 additions & 0 deletions probability/exponential_dist.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* @file
* @brief [Exponential
* Distribution](https://en.wikipedia.org/wiki/Exponential_distribution)
*
* The exponential distribution is used to model
* events occuring between a Poisson process like radioactive decay.
*
* \f[P(x, \lambda) = \lambda e^{-\lambda x}\f]
*
* Summary of variables used:
* \f$\lambda\f$ : rate parameter
*/

#include <cassert> // For assert
#include <cmath> // For std::pow
#include <iostream> // For I/O operation
#include <stdexcept> // For std::invalid_argument
#include <string> // For std::string

/**
* @namespace probability
* @brief Probability algorithms
*/
namespace probability {
/**
* @namespace exponential_dist
* @brief Functions for the [Exponential
* Distribution](https://en.wikipedia.org/wiki/Exponential_distribution)
* algorithm implementation
*/
namespace geometric_dist {
/**
* @brief the expected value of the exponential distribution
* @returns \f[\mu = \frac{1}{\lambda}\f]
*/
double exponential_expected(double lambda) {
if (lambda <= 0) {
throw std::invalid_argument("lambda must be greater than 0");
}
return 1 / lambda;
}

/**
* @brief the variance of the exponential distribution
* @returns \f[\sigma^2 = \frac{1}{\lambda^2}\f]
*/
double exponential_var(double lambda) {
if (lambda <= 0) {
throw std::invalid_argument("lambda must be greater than 0");
}
return 1 / pow(lambda, 2);
}

/**
* @brief the standard deviation of the exponential distribution
* @returns \f[\sigma = \frac{1}{\lambda}\f]
*/
double exponential_std(double lambda) {
if (lambda <= 0) {
throw std::invalid_argument("lambda must be greater than 0");
}
return 1 / lambda;
}
} // namespace geometric_dist
} // namespace probability

/**
* @brief Self-test implementations
* @returns void
*/
static void test() {
double lambda_1 = 1;
double expected_1 = 1;
double var_1 = 1;
double std_1 = 1;

double lambda_2 = 2;
double expected_2 = 0.5;
double var_2 = 0.25;
double std_2 = 0.5;

double lambda_3 = 3;
double expected_3 = 0.333333;
double var_3 = 0.111111;
double std_3 = 0.333333;

double lambda_4 = 0; // Test 0
double lambda_5 = -2.3; // Test negative value

const float threshold = 1e-3f;

std::cout << "Test for lambda = 1 \n";
assert(
std::abs(expected_1 - probability::geometric_dist::exponential_expected(
lambda_1)) < threshold);
assert(std::abs(var_1 - probability::geometric_dist::exponential_var(
lambda_1)) < threshold);
assert(std::abs(std_1 - probability::geometric_dist::exponential_std(
lambda_1)) < threshold);
std::cout << "ALL TEST PASSED\n\n";

std::cout << "Test for lambda = 2 \n";
assert(
std::abs(expected_2 - probability::geometric_dist::exponential_expected(
lambda_2)) < threshold);
assert(std::abs(var_2 - probability::geometric_dist::exponential_var(
lambda_2)) < threshold);
assert(std::abs(std_2 - probability::geometric_dist::exponential_std(
lambda_2)) < threshold);
std::cout << "ALL TEST PASSED\n\n";

std::cout << "Test for lambda = 3 \n";
assert(
std::abs(expected_3 - probability::geometric_dist::exponential_expected(
lambda_3)) < threshold);
assert(std::abs(var_3 - probability::geometric_dist::exponential_var(
lambda_3)) < threshold);
assert(std::abs(std_3 - probability::geometric_dist::exponential_std(
lambda_3)) < threshold);
std::cout << "ALL TEST PASSED\n\n";

std::cout << "Test for lambda = 0 \n";
try {
probability::geometric_dist::exponential_expected(lambda_4);
probability::geometric_dist::exponential_var(lambda_4);
probability::geometric_dist::exponential_std(lambda_4);
} catch (std::invalid_argument& err) {
assert(std::string(err.what()) == "lambda must be greater than 0");
}
std::cout << "ALL TEST PASSED\n\n";

std::cout << "Test for lambda = -2.3 \n";
try {
probability::geometric_dist::exponential_expected(lambda_5);
probability::geometric_dist::exponential_var(lambda_5);
probability::geometric_dist::exponential_std(lambda_5);
} catch (std::invalid_argument& err) {
assert(std::string(err.what()) == "lambda must be greater than 0");
}
std::cout << "ALL TEST PASSED\n\n";
}

/**
* @brief Main function
* @return 0 on exit
*/
int main() {
test(); // Self test implementation
return 0;
}
Loading

0 comments on commit 3da5e2a

Please sign in to comment.