diff --git a/code_review/permutations_20190423_1832_1/readme.md b/code_review/permutations_20190423_1832_1/readme.md new file mode 100644 index 0000000..c2314cf --- /dev/null +++ b/code_review/permutations_20190423_1832_1/readme.md @@ -0,0 +1,31 @@ + +# Overview + +The task is to compute all the permutations for a given vector of integers (but of course the specific integer type is not relevant for the solution) + +The strategy is based on recursion + iterations + +At each recursion, the state consists of + +- the root sequence `a` which is the set of elements already placed + +- the remaining elements set `b` which is the set of elements still to be placed + +Inside the recursion, a loop places the `N(i)` (with `i` recursion index and) remaining elements producing the same amount of new root sequences and a new recursion is started so that `N(i+1)=N(i)-1` hence meaning the overall complexity is `O(N!)` as expected + +The recursion ends when there are no more elements to place hence `b.empty()` is true + +Each recursion set ends with a valid sequence hence they are all merged together in a final list of sequences + +- [Article on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217939/compute-all-the-permutations-for-a-given-vector-of-integers) + +# Solutions + +- [Sol1](sol.cpp) + + + + + + + diff --git a/code_review/permutations_20190423_1832_1/sol.cpp b/code_review/permutations_20190423_1832_1/sol.cpp new file mode 100644 index 0000000..a1e8766 --- /dev/null +++ b/code_review/permutations_20190423_1832_1/sol.cpp @@ -0,0 +1,53 @@ +#include +#include +using namespace std; + +vector remove_item (const vector& a, const unsigned int id) +{ + vector res; + for(unsigned int i=0; i add_item(const vector& a, const int b) +{ + vector res=a; + res.push_back(b); + return res; +} + +vector< vector > merge(const vector< vector >& a, const vector< vector >& b) +{ + vector< vector > res=a; + for(const auto& e : b) res.push_back(e); + return res; +} + + + +vector< vector > permutations(const vector& b, const vector& a={}) +{ + + if(b.empty()) return { a }; + + vector< vector > res; + for(unsigned int i=0; i +#include +using namespace std; + +vector a = {5,6,7,8,9,10,11, 1,2,3,4}; + +unsigned int solve(const vector& a, unsigned int l=0, unsigned int r=0) +{ + if(a.empty()) throw runtime_error("Empty"); + if(a.size()==1) return 0; + if(r==0) r=a.size()-1; ///< Overwrite the invalid initialization with the right value, unfortunately it is not possible to do this in function declaration + if(a[l] < a[r]) return l; ///< Sorted in Ascending Order + if(r-l==1) return r; + const auto m = (r+l)/2; + if(a[m] > a[l]) return solve(a, m, r); + return solve(a, l, m); +} + +int main() { + // your code goes here + cout << "Min=" << a[solve(a)]; + return 0; +} + + + + + + + diff --git a/code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/iterator_based1.cpp b/code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/iterator_based1.cpp new file mode 100644 index 0000000..ee67b71 --- /dev/null +++ b/code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/iterator_based1.cpp @@ -0,0 +1,31 @@ + +#include +#include +#include +using namespace std; + +vector a = {5,6,7,8,9,10,11, 1,2,3,4}; + +vector::iterator solve(const vector::iterator l, const vector::iterator r) +{ + if(l==r) return r; ///< Covers the single element array case + if(*l < *r) return l; ///< Sorted in Ascending Order + if(r-l==1) return r; + const auto m = l + distance(l,r)/2; + if(*m > *l) return solve(m, r); + return solve(l, m); +} + +int main() { + // your code goes here + cout << "Min=" << *solve(a.begin(), a.end()-1); + return 0; +} + + + + + + + + diff --git a/code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/readme.md b/code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/readme.md new file mode 100644 index 0000000..1ae26fd --- /dev/null +++ b/code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/readme.md @@ -0,0 +1,64 @@ + +# Overview + +Here is my minimal solution about the problem + +- the strategy is divide-and-conquer for the reasons already explained by @papagaga + +- it is based on the idea that before the rotation the array has this structure + +``` +[m .. p P .. M] +``` + +with + +- `m` min + +- `M` max + +- `p` pivot + +- `P` next to the pivot so that `P>p` + + +- while after the rotation it has the following structure + +``` +[P .. M m .. p] +``` + +so the idea is to update the `l` left cursor and `r` right cursor so that `v[l] > v[r]` with a divide and conquer strategy so to have `O(LogN)` complexity and ultimately the final condition is `l` and `r` are contiguous +and the first identifies `M` while the second identifies `m` hence return the last one + +**EDIT** Following @papagaga suggestion I provide 2 implementations + +- [Article on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217897/find-the-smallest-element-in-a-sorted-and-rotated-array/217949#217949) + + +## 1. Index based solution + +[Index based](index_based1.cpp) + +Comments + +- Added the empty array case management using Exception +- An alternative could have been using Maybe Monad (a Boost Optional) to represent non meaningful results + + +## 2. Iterators based solution + +[Iterators based](iterator_based1.cpp) + +Comments + +- Working with iterators allows to represent invalid values so no need for Exception and explicit Maybe Monad as the iterator type is one +- The first check automatically manages the one element case +- The empty array case should be managed before calling this function as it expects both the iterators point to valid elements + + + + + + +