-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from NicolaBernini/code_review_20190423_1832_1
Code review 20190423 1832 1
- Loading branch information
Showing
6 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#include <iostream> | ||
#include <vector> | ||
using namespace std; | ||
|
||
vector<int> remove_item (const vector<int>& a, const unsigned int id) | ||
{ | ||
vector<int> res; | ||
for(unsigned int i=0; i<a.size(); ++i) if(i!=id) res.push_back(a[i]); | ||
return res; | ||
} | ||
|
||
|
||
vector<int> add_item(const vector<int>& a, const int b) | ||
{ | ||
vector<int> res=a; | ||
res.push_back(b); | ||
return res; | ||
} | ||
|
||
vector< vector<int> > merge(const vector< vector<int> >& a, const vector< vector<int> >& b) | ||
{ | ||
vector< vector<int> > res=a; | ||
for(const auto& e : b) res.push_back(e); | ||
return res; | ||
} | ||
|
||
|
||
|
||
vector< vector<int> > permutations(const vector<int>& b, const vector<int>& a={}) | ||
{ | ||
|
||
if(b.empty()) return { a }; | ||
|
||
vector< vector<int> > res; | ||
for(unsigned int i=0; i<b.size(); ++i) res=merge(res, permutations(remove_item(b,i), add_item(a, b[i]))); | ||
return res; | ||
} | ||
|
||
int main() { | ||
// your code goes here | ||
|
||
auto res = permutations({1,2,3,4,5}); | ||
cout << "Sol Num = " << res.size() << endl; | ||
for(const auto& a : res) | ||
{ | ||
for(const auto& b : a) cout << to_string(b) << " "; | ||
cout << endl; | ||
} | ||
return 0; | ||
} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
# Overview | ||
|
||
This regards [Code Reviews](https://codereview.stackexchange.com/) related code submissions | ||
|
||
# Permutations | ||
|
||
- Compute all the possible permutations for a given vector | ||
- [Article](permutations_20190423_1832_1/readme.md) | ||
- [Post on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217939/compute-all-the-permutations-for-a-given-vector-of-integers) | ||
|
||
|
||
|
||
# Search in Array | ||
|
||
- Search min element in an array which was previously sorted in ascending order and then rotated with respect to a random pivot | ||
- [Article](smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/readme.md) | ||
- [Post on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217897/find-the-smallest-element-in-a-sorted-and-rotated-array/217949#217949) | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
Work in progress | ||
|
||
|
||
|
||
|
||
|
31 changes: 31 additions & 0 deletions
31
code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/index_based1.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
#include <iostream> | ||
#include <vector> | ||
using namespace std; | ||
|
||
vector<int> a = {5,6,7,8,9,10,11, 1,2,3,4}; | ||
|
||
unsigned int solve(const vector<int>& 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; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
31 changes: 31 additions & 0 deletions
31
code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/iterator_based1.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
#include <iostream> | ||
#include <vector> | ||
#include <iterator> | ||
using namespace std; | ||
|
||
vector<int> a = {5,6,7,8,9,10,11, 1,2,3,4}; | ||
|
||
vector<int>::iterator solve(const vector<int>::iterator l, const vector<int>::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; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
64 changes: 64 additions & 0 deletions
64
code_review/smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/readme.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
||
|
||
|
||
|
||
|
||
|
||
|