From 0f20cdcf8f49c2b8f2c128a2ac7b22819a44a680 Mon Sep 17 00:00:00 2001 From: Suman Mondal <94859440+sumanbmondal@users.noreply.github.com> Date: Tue, 7 Feb 2023 01:41:52 +0530 Subject: [PATCH] feat: add maximum circular subarray sum (#2242) * Create maximum_circular_subarray.cpp * Delete maximum_circular_subarray.cpp * Create maximum_circular_subarray.cpp * Update maximum_circular_subarray.cpp Used the template provided. * updating DIRECTORY.md * Update maximum_circular_subarray.cpp * Update maximum_circular_subarray.cpp * Update maximum_circular_subarray.cpp * Update maximum_circular_subarray.cpp * Update maximum_circular_subarray.cpp * Update dynamic_programming/maximum_circular_subarray.cpp Co-authored-by: David Leal * Update maximum_circular_subarray.cpp * Update dynamic_programming/maximum_circular_subarray.cpp Co-authored-by: David Leal * Update dynamic_programming/maximum_circular_subarray.cpp Co-authored-by: David Leal * Update dynamic_programming/maximum_circular_subarray.cpp Co-authored-by: David Leal * Update dynamic_programming/maximum_circular_subarray.cpp Co-authored-by: David Leal * Update dynamic_programming/maximum_circular_subarray.cpp Co-authored-by: David Leal * Update dynamic_programming/maximum_circular_subarray.cpp Co-authored-by: David Leal * Update maximum_circular_subarray.cpp Fixed the comments according to @krishnacx * chore: apply suggestions from code review --------- Co-authored-by: Suman Mondal <94859440+sumanarlert@users.noreply.github.com> Co-authored-by: github-actions[bot] Co-authored-by: David Leal --- DIRECTORY.md | 1 + .../maximum_circular_subarray.cpp | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 dynamic_programming/maximum_circular_subarray.cpp diff --git a/DIRECTORY.md b/DIRECTORY.md index 844d4c9fd..521102995 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -108,6 +108,7 @@ * [Longest Increasing Subsequence (Nlogn)](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/longest_increasing_subsequence_(nlogn).cpp) * [Longest Palindromic Subsequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/longest_palindromic_subsequence.cpp) * [Matrix Chain Multiplication](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/matrix_chain_multiplication.cpp) + * [Maximum Circular Subarray](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/maximum_circular_subarray.cpp) * [Minimum Edit Distance](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/minimum_edit_distance.cpp) * [Palindrome Partitioning](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/palindrome_partitioning.cpp) * [Partition Problem](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/partition_problem.cpp) diff --git a/dynamic_programming/maximum_circular_subarray.cpp b/dynamic_programming/maximum_circular_subarray.cpp new file mode 100644 index 000000000..d32ac64e9 --- /dev/null +++ b/dynamic_programming/maximum_circular_subarray.cpp @@ -0,0 +1,90 @@ +/** +* @file +* @brief C++ program for maximum contiguous circular sum problem using [Kadane's Algorithm](https://en.wikipedia.org/wiki/Maximum_subarray_problem) +* @details +* The idea is to modify Kadane’s algorithm to find a minimum contiguous subarray sum and the maximum contiguous subarray sum, +* then check for the maximum value between the max_value and the value left after subtracting min_value from the total sum. +* For more information, check [Geeks For Geeks](https://www.geeksforgeeks.org/maximum-contiguous-circular-sum/) explanation page. +*/ + +#include /// for assert +#include /// for IO operations +#include /// for std::vector + + +/** + * @namespace dynamic_programming + * @brief Dynamic Programming algorithms + */ +namespace dynamic_programming { +/** + * @brief returns the maximum contiguous circular sum of an array + * + * @param arr is the array/vector + * @return int which is the maximum sum + */ +int maxCircularSum(std::vector& arr) +{ + // Edge Case + if (arr.size() == 1) + return arr[0]; + + // Sum variable which stores total sum of the array. + int sum = 0; + for (int i = 0; i < arr.size(); i++) { + sum += arr[i]; + } + + // Every variable stores first value of the array. + int current_max = arr[0], max_so_far = arr[0], current_min = arr[0], min_so_far = arr[0]; + + // Concept of Kadane's Algorithm + for (int i = 1; i < arr.size(); i++) { + // Kadane's Algorithm to find Maximum subarray sum. + current_max = std::max(current_max + arr[i], arr[i]); + max_so_far = std::max(max_so_far, current_max); + + // Kadane's Algorithm to find Minimum subarray sum. + current_min = std::min(current_min + arr[i], arr[i]); + min_so_far = std::min(min_so_far, current_min); + } + + if (min_so_far == sum) + return max_so_far; + + // Return the maximum value + return std::max(max_so_far, sum - min_so_far); +} +} // namespace dynamic_programming + +/** + * @brief Self-test implementation + * @returns void + */ +static void test() { + // Description of the test + // Input: arr[] = {8, -8, 9, -9, 10, -11, 12} + // Output: 22 + // Explanation: Subarray 12, 8, -8, 9, -9, 10 gives the maximum sum, that is 22. + + int n = 7; // size of the array + std::vector arr = {8, -8, 9, -9, 10, -11, 12}; + assert(dynamic_programming::maxCircularSum(arr) == 22); // this ensures that the algorithm works as expected + + arr = {8, -8, 10, -9, 10, -11, 12}; + assert(dynamic_programming::maxCircularSum(arr) == 23); + + std::cout << "All tests have successfully passed!\n"; +} + + +/** + * @brief Main function + * @param argc commandline argument count (ignored) + * @param argv commandline array of arguments (ignored) + * @returns 0 on exit + */ +int main(int argc, char *argv[]) { + test(); // run self-test implementations + return 0; +}