Skip to content

Commit

Permalink
Update flip-game-ii.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
kamyu104 committed Oct 16, 2015
1 parent 5944312 commit 8581c73
Showing 1 changed file with 65 additions and 3 deletions.
68 changes: 65 additions & 3 deletions C++/flip-game-ii.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,71 @@
// Time: O(n + c^3 * 2^c * logc)
// Space: O(c * 2^c)

// hash solution.
class Solution {
public:
struct multiset_hash {
std::size_t operator() (const multiset<int>& set) const {
string set_string;
for (const auto& i : set) {
set_string.append(to_string(i) + " ");
}
return hash<string>()(set_string);
}
};

bool canWin(string s) {
const int n = s.length();
multiset<int> consecutives;
for (int i = 0; i < n - 1; ++i) { // O(n) time
if (s[i] == '+') {
int c = 1;
for (; i < n - 1 && s[i + 1] == '+'; ++i, ++c);
if (c >= 2) {
consecutives.emplace(c);
}
}
}
return canWinHelper(consecutives);
}

private:
bool canWinHelper(const multiset<int>& consecutives) {
if (!lookup_.count(consecutives)) {
bool is_win = false;
for (auto it = consecutives.cbegin(); !is_win && it != consecutives.cend(); ++it) {
const int c = *it;
multiset<int> next_consecutives(consecutives);
next_consecutives.erase(next_consecutives.find(c));
for (int i = 0; !is_win && i < c - 1; ++i) {
if (i >= 2) {
next_consecutives.emplace(i);
}
if (c - 2 - i >= 2) {
next_consecutives.emplace(c - 2 - i);
}
is_win = !canWinHelper(next_consecutives);
if (i >= 2) {
next_consecutives.erase(next_consecutives.find(i));
}
if (c - 2 - i >= 2) {
next_consecutives.erase(next_consecutives.find(c - 2 - i));
}
lookup_[consecutives] = is_win;
}
}
}
return lookup_[consecutives];
}
unordered_map<multiset<int>, bool, multiset_hash> lookup_;
};


// Time: O(n + c * n * 2^c), try all the possible game strings,
// and each string would have c choices to become the next string
// Space: O(n * 2^c), keep all the possible game strings

// hash solution.
class Solution {
class Solution2 {
public:
bool canWin(string s) {
if (!lookup_.count(s)) {
Expand All @@ -30,7 +92,7 @@ class Solution {
// Time: O(n * c!), n is length of string, c is count of "++"
// Space: O(c), recursion would be called at most c in depth.
// Besides, no extra space in each depth for the modified string.
class Solution2 {
class Solution3 {
public:
bool canWin(string s) {
const int n = s.length();
Expand Down

0 comments on commit 8581c73

Please sign in to comment.