From a3549083e84a64cdfb5bc34a9f4536e239b8a98a Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Sat, 5 Oct 2024 13:57:03 +0530 Subject: [PATCH 01/10] Longest Increasing subsequence using binary search most optimal approach for this problem --- ....cpp_68d930cfff228b4ee2fead04a597072f.prob | 1 + ...easing_Subsequence_using_binary_search.cpp | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob create mode 100644 search/Longest_Increasing_Subsequence_using_binary_search.cpp diff --git a/search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob b/search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob new file mode 100644 index 00000000000..41dda85adf8 --- /dev/null +++ b/search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob @@ -0,0 +1 @@ +{"name":"Local: Longest_Increasing_Subsequence","url":"c:\\Users\\ASUS\\OneDrive\\Desktop\\hack_fest_2024\\C-Plus-Plus\\search\\Longest_Increasing_Subsequence.cpp","tests":[{"id":1728116499174,"input":"","output":""}],"interactive":false,"memoryLimit":1024,"timeLimit":3000,"srcPath":"c:\\Users\\ASUS\\OneDrive\\Desktop\\hack_fest_2024\\C-Plus-Plus\\search\\Longest_Increasing_Subsequence.cpp","group":"local","local":true} \ No newline at end of file diff --git a/search/Longest_Increasing_Subsequence_using_binary_search.cpp b/search/Longest_Increasing_Subsequence_using_binary_search.cpp new file mode 100644 index 00000000000..051143a37b8 --- /dev/null +++ b/search/Longest_Increasing_Subsequence_using_binary_search.cpp @@ -0,0 +1,62 @@ + +// Given an integer array nums, return the length of the longest strictly increasing subsequence. + +// The longest increasing subsequence is described as a subsequence of an array where: +// All elements of the subsequence are in increasing order. +// This subsequence itself is of the longest length possible. + +// For solving this problem we have Three Approaches :- + +// Approach 1 :- Using Brute Force +// The first approach that came to your mind is the Brute Force approach where we generate all subsequences and then manually filter the subsequences whose elements come in increasing order and then return the longest such subsequence. +// Time Complexity :- O(2^n) +// It's time complexity is exponential. Therefore we will try some other approaches. + +// Approach 2 :- Using Dynamic Programming +// To generate all subsequences we will use recursion and in the recursive logic we will figure out a way to solve this problem. +// Recursive Logic to solve this problem:- +// 1. We only consider the element in the subsequence if the element is grater then the last element present in the subsequence +// 2. When we consider the element we will increase the length of subsequence by 1 +// Time Complexity: O(N*N) +// Space Complexity: O(N*N) + O(N) + +// This approach is better then the previous Brute Force approach so, we can consider this approach. + +// But when the Constraints for the problem is very larger then this approach fails + +// Approach 3 :- Using Binary Search +// Other approaches use additional space to create a new subsequence Array. Instead, this solution uses the existing nums Array to build the subsequence array. We can do this because the length of the subsequence array will never be longer than the current index. + +// Time complexity: O(n∗log(n)) +// Space complexity: O(1) + +// This approach consider Most optimal Approach for solving this problem + +// Implementaion:- + +#include +#include +using namespace std; + +int Longest_Increasing_Subsequence_using_binary_search(vector& nums){ + if(nums.size() == 0) return 0; + + vector ans; + ans.push_back(nums[0]); + for(int i=1;i ans.back()){ + ans.push_back(nums[i]); + } + else{ + int idx = lower_bound(ans.begin(),ans.end(),nums[i]) -ans.begin(); + ans[idx] = nums[i]; + } + } + return ans.size(); +} + +int main(){ + vector arr = {10,9,2,5,3,7,101,18}; + cout<<"longest increasing subsequence : "< Date: Sat, 5 Oct 2024 14:02:51 +0530 Subject: [PATCH 02/10] Longest Increasing subsequence using binary search most optimal approach for this problem --- ...reasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob | 1 - 1 file changed, 1 deletion(-) delete mode 100644 search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob diff --git a/search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob b/search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob deleted file mode 100644 index 41dda85adf8..00000000000 --- a/search/.cph/.Longest_Increasing_Subsequence.cpp_68d930cfff228b4ee2fead04a597072f.prob +++ /dev/null @@ -1 +0,0 @@ -{"name":"Local: Longest_Increasing_Subsequence","url":"c:\\Users\\ASUS\\OneDrive\\Desktop\\hack_fest_2024\\C-Plus-Plus\\search\\Longest_Increasing_Subsequence.cpp","tests":[{"id":1728116499174,"input":"","output":""}],"interactive":false,"memoryLimit":1024,"timeLimit":3000,"srcPath":"c:\\Users\\ASUS\\OneDrive\\Desktop\\hack_fest_2024\\C-Plus-Plus\\search\\Longest_Increasing_Subsequence.cpp","group":"local","local":true} \ No newline at end of file From 8697330637107edf79ef3e1f36b5cd3a1c29b28d Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Sat, 5 Oct 2024 20:01:11 +0530 Subject: [PATCH 03/10] Longest Increasing subsequence using binary search most optimal approach for this problem (Modified) --- ...easing_Subsequence_using_binary_search.cpp | 105 ++++++++++++------ 1 file changed, 72 insertions(+), 33 deletions(-) diff --git a/search/Longest_Increasing_Subsequence_using_binary_search.cpp b/search/Longest_Increasing_Subsequence_using_binary_search.cpp index 051143a37b8..fc7603d91cb 100644 --- a/search/Longest_Increasing_Subsequence_using_binary_search.cpp +++ b/search/Longest_Increasing_Subsequence_using_binary_search.cpp @@ -1,47 +1,66 @@ -// Given an integer array nums, return the length of the longest strictly increasing subsequence. +/****************************************************************************** + * @details +Given an integer array nums, return the length of the longest strictly +increasing subsequence. -// The longest increasing subsequence is described as a subsequence of an array where: -// All elements of the subsequence are in increasing order. -// This subsequence itself is of the longest length possible. +The longest increasing subsequence is described as a subsequence of an array +where: All elements of the subsequence are in increasing order. This subsequence +itself is of the longest length possible. -// For solving this problem we have Three Approaches :- +For solving this problem we have Three Approaches :- -// Approach 1 :- Using Brute Force -// The first approach that came to your mind is the Brute Force approach where we generate all subsequences and then manually filter the subsequences whose elements come in increasing order and then return the longest such subsequence. -// Time Complexity :- O(2^n) -// It's time complexity is exponential. Therefore we will try some other approaches. +Approach 1 :- Using Brute Force +The first approach that came to your mind is the Brute Force approach where we +generate all subsequences and then manually filter the subsequences whose +elements come in increasing order and then return the longest such subsequence. +Time Complexity :- O(2^n) +It's time complexity is exponential. Therefore we will try some other +approaches. -// Approach 2 :- Using Dynamic Programming -// To generate all subsequences we will use recursion and in the recursive logic we will figure out a way to solve this problem. -// Recursive Logic to solve this problem:- -// 1. We only consider the element in the subsequence if the element is grater then the last element present in the subsequence -// 2. When we consider the element we will increase the length of subsequence by 1 -// Time Complexity: O(N*N) -// Space Complexity: O(N*N) + O(N) +Approach 2 :- Using Dynamic Programming +To generate all subsequences we will use recursion and in the recursive logic we +will figure out a way to solve this problem. Recursive Logic to solve this +problem:- +1. We only consider the element in the subsequence if the element is grater then +the last element present in the subsequence +2. When we consider the element we will increase the length of subsequence by 1 +Time Complexity: O(N*N) +Space Complexity: O(N*N) + O(N) -// This approach is better then the previous Brute Force approach so, we can consider this approach. +This approach is better then the previous Brute Force approach so, we can +consider this approach. -// But when the Constraints for the problem is very larger then this approach fails +But when the Constraints for the problem is very larger then this approach fails -// Approach 3 :- Using Binary Search -// Other approaches use additional space to create a new subsequence Array. Instead, this solution uses the existing nums Array to build the subsequence array. We can do this because the length of the subsequence array will never be longer than the current index. +Approach 3 :- Using Binary Search +Other approaches use additional space to create a new subsequence Array. +Instead, this solution uses the existing nums Array to build the subsequence +array. We can do this because the length of the subsequence array will never be +longer than the current index. -// Time complexity: O(n∗log(n)) -// Space complexity: O(1) +Time complexity: O(n∗log(n)) +Space complexity: O(1) -// This approach consider Most optimal Approach for solving this problem +This approach consider Most optimal Approach for solving this problem -// Implementaion:- + *******************************************************************************/ -#include -#include -using namespace std; +#include /// for std::assert +#include /// for IO operations +#include /// for std::vector -int Longest_Increasing_Subsequence_using_binary_search(vector& nums){ +/** + * @brief Function to find the length of Longest Increasing Subsequence (LIS) + * using Binary Search + * @param nums Input integer array + * @return Length of the longest increasing subsequence + */ +int Longest_Increasing_Subsequence_using_binary_search(std::vector& nums){ + if(nums.size() == 0) return 0; - vector ans; + std::vector ans; ans.push_back(nums[0]); for(int i=1;i ans.back()){ @@ -55,8 +74,28 @@ int Longest_Increasing_Subsequence_using_binary_search(vector& nums){ return ans.size(); } -int main(){ - vector arr = {10,9,2,5,3,7,101,18}; - cout<<"longest increasing subsequence : "< arr = {10, 9, 2, 5, 3, 7, 101, 18}; + assert(Longest_Increasing_Subsequence_using_binary_search(arr) == 4); + + std::vector arr2 = {0, 1, 0, 3, 2, 3}; + assert(Longest_Increasing_Subsequence_using_binary_search(arr2) == 4); + + std::vector arr3 = {7, 7, 7, 7, 7, 7, 7}; + assert(Longest_Increasing_Subsequence_using_binary_search(arr3) == 1); + + std::cout << "All tests have successfully passed!\n"; +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + tests(); + return 0; } From 220ca43f3555ccefaafd4831e8fb706159bb3290 Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Mon, 7 Oct 2024 19:37:02 +0530 Subject: [PATCH 04/10] Longest Increasing subsequence using binary search most optimal approach for this problem --- ...easing_Subsequence_using_binary_search.cpp | 85 ++++--------------- 1 file changed, 18 insertions(+), 67 deletions(-) diff --git a/search/Longest_Increasing_Subsequence_using_binary_search.cpp b/search/Longest_Increasing_Subsequence_using_binary_search.cpp index fc7603d91cb..8a8c935bee1 100644 --- a/search/Longest_Increasing_Subsequence_using_binary_search.cpp +++ b/search/Longest_Increasing_Subsequence_using_binary_search.cpp @@ -1,73 +1,24 @@ - -/****************************************************************************** - * @details -Given an integer array nums, return the length of the longest strictly -increasing subsequence. - -The longest increasing subsequence is described as a subsequence of an array -where: All elements of the subsequence are in increasing order. This subsequence -itself is of the longest length possible. - -For solving this problem we have Three Approaches :- - -Approach 1 :- Using Brute Force -The first approach that came to your mind is the Brute Force approach where we -generate all subsequences and then manually filter the subsequences whose -elements come in increasing order and then return the longest such subsequence. -Time Complexity :- O(2^n) -It's time complexity is exponential. Therefore we will try some other -approaches. - -Approach 2 :- Using Dynamic Programming -To generate all subsequences we will use recursion and in the recursive logic we -will figure out a way to solve this problem. Recursive Logic to solve this -problem:- -1. We only consider the element in the subsequence if the element is grater then -the last element present in the subsequence -2. When we consider the element we will increase the length of subsequence by 1 -Time Complexity: O(N*N) -Space Complexity: O(N*N) + O(N) - -This approach is better then the previous Brute Force approach so, we can -consider this approach. - -But when the Constraints for the problem is very larger then this approach fails - -Approach 3 :- Using Binary Search -Other approaches use additional space to create a new subsequence Array. -Instead, this solution uses the existing nums Array to build the subsequence -array. We can do this because the length of the subsequence array will never be -longer than the current index. - -Time complexity: O(n∗log(n)) -Space complexity: O(1) - -This approach consider Most optimal Approach for solving this problem - - *******************************************************************************/ - -#include /// for std::assert -#include /// for IO operations -#include /// for std::vector +#include /// for std::assert +#include /// for IO operations +#include /// for std::vector +#include /// for std::lower_bound /** - * @brief Function to find the length of Longest Increasing Subsequence (LIS) + * @brief Function to find the length of the Longest Increasing Subsequence (LIS) * using Binary Search - * @param nums Input integer array - * @return Length of the longest increasing subsequence + * @param nums The input vector of integers + * @return The length of the longest increasing subsequence */ -int Longest_Increasing_Subsequence_using_binary_search(std::vector& nums){ - - if(nums.size() == 0) return 0; +int longest_increasing_subsequence_using_binary_search(std::vector& nums) { + if (nums.empty()) return 0; std::vector ans; ans.push_back(nums[0]); - for(int i=1;i ans.back()){ + for (int i = 1; i < nums.size(); i++) { + if (nums[i] > ans.back()) { ans.push_back(nums[i]); - } - else{ - int idx = lower_bound(ans.begin(),ans.end(),nums[i]) -ans.begin(); + } else { + int idx = std::lower_bound(ans.begin(), ans.end(), nums[i]) - ans.begin(); ans[idx] = nums[i]; } } @@ -75,24 +26,24 @@ int Longest_Increasing_Subsequence_using_binary_search(std::vector& nums){ } /** - * @brief test implementations + * @brief Test cases for Longest Increasing Subsequence function * @returns void */ static void tests() { std::vector arr = {10, 9, 2, 5, 3, 7, 101, 18}; - assert(Longest_Increasing_Subsequence_using_binary_search(arr) == 4); + assert(longest_increasing_subsequence_using_binary_search(arr) == 4); std::vector arr2 = {0, 1, 0, 3, 2, 3}; - assert(Longest_Increasing_Subsequence_using_binary_search(arr2) == 4); + assert(longest_increasing_subsequence_using_binary_search(arr2) == 4); std::vector arr3 = {7, 7, 7, 7, 7, 7, 7}; - assert(Longest_Increasing_Subsequence_using_binary_search(arr3) == 1); + assert(longest_increasing_subsequence_using_binary_search(arr3) == 1); std::cout << "All tests have successfully passed!\n"; } /** - * @brief Main function + * @brief Main function to run tests * @returns 0 on exit */ int main() { From a9c309e1d40383f1a53c0f746a0cc6440b2d252f Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Mon, 7 Oct 2024 20:05:54 +0530 Subject: [PATCH 05/10] Longest Increasing subsequence using binary search most optimal approach for this problem(done) --- ...easing_Subsequence_using_binary_search.cpp | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/search/Longest_Increasing_Subsequence_using_binary_search.cpp b/search/Longest_Increasing_Subsequence_using_binary_search.cpp index 8a8c935bee1..1e190bfbdaa 100644 --- a/search/Longest_Increasing_Subsequence_using_binary_search.cpp +++ b/search/Longest_Increasing_Subsequence_using_binary_search.cpp @@ -1,3 +1,54 @@ + +/** + * @file + * @brief find the length of the Longest Increasing Subsequence (LIS) + * using Binary Search(https://en.wikipedia.org/wiki/Longest_increasing_subsequence) + * @details + * Given an integer array nums, return the length of the longest strictly + * increasing subsequence. + * The longest increasing subsequence is described as a subsequence of an array + * where: All elements of the subsequence are in increasing order. This subsequence + * itself is of the longest length possible. + + * For solving this problem we have Three Approaches :- + + * Approach 1 :- Using Brute Force + * The first approach that came to your mind is the Brute Force approach where we + * generate all subsequences and then manually filter the subsequences whose + * elements come in increasing order and then return the longest such subsequence. + * Time Complexity :- O(2^n) + * It's time complexity is exponential. Therefore we will try some other + * approaches. + + * Approach 2 :- Using Dynamic Programming + * To generate all subsequences we will use recursion and in the recursive logic we + * will figure out a way to solve this problem. Recursive Logic to solve this + * problem:- + * 1. We only consider the element in the subsequence if the element is grater then + * the last element present in the subsequence + * 2. When we consider the element we will increase the length of subsequence by 1 + * Time Complexity: O(N*N) + * Space Complexity: O(N*N) + O(N) + + * This approach is better then the previous Brute Force approach so, we can + * consider this approach. + + * But when the Constraints for the problem is very larger then this approach fails + + * Approach 3 :- Using Binary Search + * Other approaches use additional space to create a new subsequence Array. + * Instead, this solution uses the existing nums Array to build the subsequence + * array. We can do this because the length of the subsequence array will never be + * longer than the current index. + + * Time complexity: O(n∗log(n)) + * Space complexity: O(1) + + * This approach consider Most optimal Approach for solving this problem + + * @author [Naman Jain](https://github.com/namanmodi65) + */ + #include /// for std::assert #include /// for IO operations #include /// for std::vector From 5d87f42e461990ebefde044c0069e119cb0e6396 Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Thu, 10 Oct 2024 19:36:46 +0530 Subject: [PATCH 06/10] Longest Increasing subsequence using binary search most optimal approach for this problem --- ...Longest_Increasing_Subsequence_using_binary_search.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/search/Longest_Increasing_Subsequence_using_binary_search.cpp b/search/Longest_Increasing_Subsequence_using_binary_search.cpp index 1e190bfbdaa..6506a0f71a0 100644 --- a/search/Longest_Increasing_Subsequence_using_binary_search.cpp +++ b/search/Longest_Increasing_Subsequence_using_binary_search.cpp @@ -2,7 +2,7 @@ /** * @file * @brief find the length of the Longest Increasing Subsequence (LIS) - * using Binary Search(https://en.wikipedia.org/wiki/Longest_increasing_subsequence) + * using [Binary Search](https://en.wikipedia.org/wiki/Longest_increasing_subsequence) * @details * Given an integer array nums, return the length of the longest strictly * increasing subsequence. @@ -90,6 +90,12 @@ static void tests() { std::vector arr3 = {7, 7, 7, 7, 7, 7, 7}; assert(longest_increasing_subsequence_using_binary_search(arr3) == 1); + std::vector arr4 = {-10, -1, -5, 0, 5, 1, 2}; + assert(longest_increasing_subsequence_using_binary_search(arr4) == 5); + + std::vector arr5 = {}; + assert(longest_increasing_subsequence_using_binary_search(arr5) == 0); + std::cout << "All tests have successfully passed!\n"; } From 245b9987b212c1a6ef6c5a50760f0bbe027b9789 Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Thu, 10 Oct 2024 20:10:58 +0530 Subject: [PATCH 07/10] Floyd warshall --- graph/.vscode/settings.json | 53 +++++++++++++++++ graph/floyd_warshall.cpp | 112 ++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 graph/.vscode/settings.json create mode 100644 graph/floyd_warshall.cpp diff --git a/graph/.vscode/settings.json b/graph/.vscode/settings.json new file mode 100644 index 00000000000..d8e6a3d918a --- /dev/null +++ b/graph/.vscode/settings.json @@ -0,0 +1,53 @@ +{ + "files.associations": { + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "random": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/graph/floyd_warshall.cpp b/graph/floyd_warshall.cpp new file mode 100644 index 00000000000..e7bf0d0f770 --- /dev/null +++ b/graph/floyd_warshall.cpp @@ -0,0 +1,112 @@ +/** + * @file + * @brief Find the shortest paths between all pairs of vertices in a graph using + * the [Floyd-Warshall Algorithm](https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm). + * @details + * The Floyd-Warshall algorithm is an algorithm for finding shortest paths in a + * weighted graph with positive or negative edge weights (but with no negative cycles). + * The algorithm works for both directed and undirected graphs. + * It uses dynamic programming to iteratively improve the estimate of the shortest path + * between two vertices by considering each vertex as an intermediate point. + * + * Time Complexity: O(n^3) + * where n is the number of vertices in the graph. + * + * Space Complexity: O(n^2) + * + * @author [Naman Jain](https://github.com/namanmodi65) + */ + +#include /// for std::assert +#include /// for IO operations +#include /// for std::vector +#include /// for std::numeric_limits + +/** + * @brief Function to implement Floyd-Warshall Algorithm + * @param graph The input adjacency matrix of the graph, where graph[i][j] + * represents the weight of the edge from vertex i to vertex j. + * If there is no edge, it should be set to infinity. + * @return A matrix of shortest distances between all pairs of vertices. + */ + +std::vector> floyd_warshall(std::vector>& graph) { + int n = graph.size(); + std::vector> dist = graph; + + for (int k = 0; k < n; ++k) { + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + if (dist[i][k] != std::numeric_limits::max() && + dist[k][j] != std::numeric_limits::max()) { + dist[i][j] = std::min(dist[i][j], dist[i][k] + dist[k][j]); + } + } + } + } + + for (int i = 0; i < n; ++i) { + if (dist[i][i] < 0) { + std::cerr << "Graph contains a negative cycle\n"; + return {}; + } + } + + return dist; +} + + +/** + * @brief Test cases for Floyd-Warshall algorithm + * @returns void + */ +static void tests() { + const int INF = std::numeric_limits::max(); + + std::vector> graph1 = { + {0, 5, INF, 10}, + {INF, 0, 3, INF}, + {INF, INF, 0, 1}, + {INF, INF, INF, 0} + }; + + std::vector> expected1 = { + {0, 5, 8, 9}, + {INF, 0, 3, 4}, + {INF, INF, 0, 1}, + {INF, INF, INF, 0} + }; + + assert(floyd_warshall(graph1) == expected1); + + std::vector> graph2 = { + {0, 1, INF, INF}, + {INF, 0, -1, INF}, + {INF, INF, 0, -1}, + {-1, INF, INF, 0} + }; + + std::vector> expected2 = { + {0, 1, 0, -1}, + {-1, 0, -1, -2}, + {-2, -1, 0, -1}, + {-1, 0, -1, 0} + }; + + assert(floyd_warshall(graph2) == expected2); + + std::vector> graph3 = {{0}}; + std::vector> expected3 = {{0}}; + assert(floyd_warshall(graph3) == expected3); + + std::cout << "All tests have successfully passed!\n"; +} + +/** + * @brief Main function to run tests + * @returns 0 on exit + */ +int main() { + tests(); + return 0; +} From c1b18f125b9c60aabd2f4f3994b90633dcf0e20b Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:42:08 +0530 Subject: [PATCH 08/10] Longest Increasing subsequence using binary search most optimal approach for this problem --- graph/.vscode/settings.json | 53 ----------------- graph/floyd_warshall.cpp | 112 ------------------------------------ 2 files changed, 165 deletions(-) delete mode 100644 graph/.vscode/settings.json delete mode 100644 graph/floyd_warshall.cpp diff --git a/graph/.vscode/settings.json b/graph/.vscode/settings.json deleted file mode 100644 index d8e6a3d918a..00000000000 --- a/graph/.vscode/settings.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "files.associations": { - "array": "cpp", - "atomic": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "compare": "cpp", - "concepts": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "random": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "initializer_list": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "stdexcept": "cpp", - "streambuf": "cpp", - "typeinfo": "cpp" - } -} \ No newline at end of file diff --git a/graph/floyd_warshall.cpp b/graph/floyd_warshall.cpp deleted file mode 100644 index e7bf0d0f770..00000000000 --- a/graph/floyd_warshall.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file - * @brief Find the shortest paths between all pairs of vertices in a graph using - * the [Floyd-Warshall Algorithm](https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm). - * @details - * The Floyd-Warshall algorithm is an algorithm for finding shortest paths in a - * weighted graph with positive or negative edge weights (but with no negative cycles). - * The algorithm works for both directed and undirected graphs. - * It uses dynamic programming to iteratively improve the estimate of the shortest path - * between two vertices by considering each vertex as an intermediate point. - * - * Time Complexity: O(n^3) - * where n is the number of vertices in the graph. - * - * Space Complexity: O(n^2) - * - * @author [Naman Jain](https://github.com/namanmodi65) - */ - -#include /// for std::assert -#include /// for IO operations -#include /// for std::vector -#include /// for std::numeric_limits - -/** - * @brief Function to implement Floyd-Warshall Algorithm - * @param graph The input adjacency matrix of the graph, where graph[i][j] - * represents the weight of the edge from vertex i to vertex j. - * If there is no edge, it should be set to infinity. - * @return A matrix of shortest distances between all pairs of vertices. - */ - -std::vector> floyd_warshall(std::vector>& graph) { - int n = graph.size(); - std::vector> dist = graph; - - for (int k = 0; k < n; ++k) { - for (int i = 0; i < n; ++i) { - for (int j = 0; j < n; ++j) { - if (dist[i][k] != std::numeric_limits::max() && - dist[k][j] != std::numeric_limits::max()) { - dist[i][j] = std::min(dist[i][j], dist[i][k] + dist[k][j]); - } - } - } - } - - for (int i = 0; i < n; ++i) { - if (dist[i][i] < 0) { - std::cerr << "Graph contains a negative cycle\n"; - return {}; - } - } - - return dist; -} - - -/** - * @brief Test cases for Floyd-Warshall algorithm - * @returns void - */ -static void tests() { - const int INF = std::numeric_limits::max(); - - std::vector> graph1 = { - {0, 5, INF, 10}, - {INF, 0, 3, INF}, - {INF, INF, 0, 1}, - {INF, INF, INF, 0} - }; - - std::vector> expected1 = { - {0, 5, 8, 9}, - {INF, 0, 3, 4}, - {INF, INF, 0, 1}, - {INF, INF, INF, 0} - }; - - assert(floyd_warshall(graph1) == expected1); - - std::vector> graph2 = { - {0, 1, INF, INF}, - {INF, 0, -1, INF}, - {INF, INF, 0, -1}, - {-1, INF, INF, 0} - }; - - std::vector> expected2 = { - {0, 1, 0, -1}, - {-1, 0, -1, -2}, - {-2, -1, 0, -1}, - {-1, 0, -1, 0} - }; - - assert(floyd_warshall(graph2) == expected2); - - std::vector> graph3 = {{0}}; - std::vector> expected3 = {{0}}; - assert(floyd_warshall(graph3) == expected3); - - std::cout << "All tests have successfully passed!\n"; -} - -/** - * @brief Main function to run tests - * @returns 0 on exit - */ -int main() { - tests(); - return 0; -} From 1f0e17ee5d634574f647f1695f6a66b1143f35ac Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Fri, 11 Oct 2024 23:07:21 +0530 Subject: [PATCH 09/10] Longest Increasing subsequence using binary search most optimal approach for this problem --- ...easing_Subsequence_using_binary_search.cpp | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/search/Longest_Increasing_Subsequence_using_binary_search.cpp b/search/Longest_Increasing_Subsequence_using_binary_search.cpp index 6506a0f71a0..fd1ba741d7a 100644 --- a/search/Longest_Increasing_Subsequence_using_binary_search.cpp +++ b/search/Longest_Increasing_Subsequence_using_binary_search.cpp @@ -1,4 +1,3 @@ - /** * @file * @brief find the length of the Longest Increasing Subsequence (LIS) @@ -53,27 +52,31 @@ #include /// for IO operations #include /// for std::vector #include /// for std::lower_bound +#include /// for std::uint32_t /** * @brief Function to find the length of the Longest Increasing Subsequence (LIS) * using Binary Search - * @param nums The input vector of integers + * @tparam T The type of the elements in the input vector + * @param nums The input vector of elements of type T * @return The length of the longest increasing subsequence */ -int longest_increasing_subsequence_using_binary_search(std::vector& nums) { + +template +std::uint32_t longest_increasing_subsequence_using_binary_search(std::vector& nums) { if (nums.empty()) return 0; - std::vector ans; + std::vector ans; ans.push_back(nums[0]); - for (int i = 1; i < nums.size(); i++) { + for (std::size_t i = 1; i < nums.size(); i++) { if (nums[i] > ans.back()) { ans.push_back(nums[i]); } else { - int idx = std::lower_bound(ans.begin(), ans.end(), nums[i]) - ans.begin(); + auto idx = std::lower_bound(ans.begin(), ans.end(), nums[i]) - ans.begin(); ans[idx] = nums[i]; } } - return ans.size(); + return static_cast(ans.size()); } /** @@ -93,8 +96,14 @@ static void tests() { std::vector arr4 = {-10, -1, -5, 0, 5, 1, 2}; assert(longest_increasing_subsequence_using_binary_search(arr4) == 5); - std::vector arr5 = {}; - assert(longest_increasing_subsequence_using_binary_search(arr5) == 0); + std::vector arr5 = {3.5, 1.2, 2.8, 3.1, 4.0}; + assert(longest_increasing_subsequence_using_binary_search(arr5) == 4); + + std::vector arr6 = {'a', 'b', 'c', 'a', 'd'}; + assert(longest_increasing_subsequence_using_binary_search(arr6) == 4); + + std::vector arr7 = {}; + assert(longest_increasing_subsequence_using_binary_search(arr7) == 0); std::cout << "All tests have successfully passed!\n"; } From 05632646d8eee463a6fb2bc3af7a39af7e59146a Mon Sep 17 00:00:00 2001 From: Naman Jain <103953760+namanmodi65@users.noreply.github.com> Date: Sat, 12 Oct 2024 13:54:00 +0530 Subject: [PATCH 10/10] Longest Increasing subsequence using binary search most optimal approach for this problem --- search/Longest_Increasing_Subsequence_using_binary_search.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/search/Longest_Increasing_Subsequence_using_binary_search.cpp b/search/Longest_Increasing_Subsequence_using_binary_search.cpp index fd1ba741d7a..2f83de72ecf 100644 --- a/search/Longest_Increasing_Subsequence_using_binary_search.cpp +++ b/search/Longest_Increasing_Subsequence_using_binary_search.cpp @@ -61,7 +61,6 @@ * @param nums The input vector of elements of type T * @return The length of the longest increasing subsequence */ - template std::uint32_t longest_increasing_subsequence_using_binary_search(std::vector& nums) { if (nums.empty()) return 0; @@ -113,6 +112,6 @@ static void tests() { * @returns 0 on exit */ int main() { - tests(); + tests(); // run self test implementation return 0; }